Decompiled source of Cairn v0.1.18

plugins/Cairn/Cairn.Core.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using ExtraPotions.Cairn.Config;
using ExtraPotions.Cairn.Conversion;
using ExtraPotions.Cairn.Hud;
using ExtraPotions.Cairn.Integration;
using ExtraPotions.Cairn.Localization;
using ExtraPotions.Cairn.Radius;
using ExtraPotions.Cairn.Visibility;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ExtraPotions")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (C) 2026 expDARE (ExtraPotions Meadworks)")]
[assembly: AssemblyFileVersion("0.1.18.0")]
[assembly: AssemblyInformationalVersion("0.1.18+fatal: not a git repository (or any of the parent directories): .git")]
[assembly: AssemblyProduct("Cairn.Core")]
[assembly: AssemblyTitle("Cairn.Core")]
[assembly: AssemblyVersion("0.1.18.0")]
[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 ExtraPotions.Cairn
{
	public static class CairnCore
	{
		public const string PluginGuid = "com.meadworks.cairn";

		public const string ProductName = "Cairn";

		public const string ProductVersion = "0.1.18";

		public const string Family = "Waystone";

		public const string TokenNamespace = "cairn";

		public const string TokenPrefix = "meadworks_cairn_";

		public const string DataPrefix = "Cairn.";

		public const string SupportedGameVersion = "1.0.17";
	}
}
namespace ExtraPotions.Cairn.Visibility
{
	public enum VisibilityEffect
	{
		DistanceFog,
		GroundMist,
		FogClouds,
		MistEmitters,
		OceanMist,
		MistlandsMist,
		ParticleMist,
		CaveMist,
		SnowstormFog,
		SnowGlint,
		AshlandsMist,
		AshlandsFader,
		DeepNorthMist,
		DeepNorthFader,
		AmbientOcclusion,
		Smoke
	}
	public sealed class VisibilityEffectInfo
	{
		public VisibilityEffect Effect { get; }

		public string Name { get; }

		public string Description { get; }

		internal VisibilityEffectInfo(VisibilityEffect effect, string name, string description)
		{
			Effect = effect;
			Name = name;
			Description = description;
		}

		public override string ToString()
		{
			return Name;
		}
	}
	public static class VisibilityEffects
	{
		public static IReadOnlyList<VisibilityEffectInfo> All { get; } = Array.AsReadOnly(new VisibilityEffectInfo[16]
		{
			E(VisibilityEffect.DistanceFog, "Distance Fog", "the distance fog in every biome and weather"),
			E(VisibilityEffect.GroundMist, "Ground Mist", "the ground mist near the player"),
			E(VisibilityEffect.FogClouds, "Fog Clouds", "the low fog clouds"),
			E(VisibilityEffect.MistEmitters, "Mist Emitters", "the weather mist emitters"),
			E(VisibilityEffect.OceanMist, "Ocean Mist", "the mist over the ocean"),
			E(VisibilityEffect.MistlandsMist, "Mistlands Mist", "the Mistlands mist"),
			E(VisibilityEffect.ParticleMist, "Particle Mist", "the volumetric particle mist in mist areas"),
			E(VisibilityEffect.CaveMist, "Cave Mist", "the mist inside troll caves and mountain caves"),
			E(VisibilityEffect.SnowstormFog, "Snowstorm Fog", "the snowstorm and blizzard fog"),
			E(VisibilityEffect.SnowGlint, "Snow Glint", "the blinding glint on snowfields"),
			E(VisibilityEffect.AshlandsMist, "Ashlands Mist", "the smoky Ashlands mist"),
			E(VisibilityEffect.AshlandsFader, "Ashlands Fader", "the Ashlands fader haze"),
			E(VisibilityEffect.DeepNorthMist, "Deep North Mist", "the Deep North mist"),
			E(VisibilityEffect.DeepNorthFader, "Deep North Fader", "the Deep North fader haze"),
			E(VisibilityEffect.AmbientOcclusion, "Ambient Occlusion", "the ambient occlusion haze"),
			E(VisibilityEffect.Smoke, "Smoke", "the smoke of fires")
		});

		private static VisibilityEffectInfo E(VisibilityEffect effect, string name, string description)
		{
			return new VisibilityEffectInfo(effect, name, description);
		}

		public static VisibilityEffectInfo Of(VisibilityEffect effect)
		{
			return All[(int)effect];
		}
	}
	public enum TargetAction
	{
		None,
		Deactivate,
		Restore
	}
	public static class VisibilityPolicy
	{
		public static bool IsGateLike(VisibilityEffect effect)
		{
			if (effect != VisibilityEffect.MistlandsMist && effect != VisibilityEffect.ParticleMist)
			{
				return effect == VisibilityEffect.CaveMist;
			}
			return true;
		}

		public static bool Removes(VisibilityEffect effect, bool remove, bool serverAllows, bool held)
		{
			if (remove && serverAllows)
			{
				if (held)
				{
					return !IsGateLike(effect);
				}
				return true;
			}
			return false;
		}

		public static BlockReason Reason(VisibilityEffect effect, bool remove, bool serverAllows, SessionFacts facts)
		{
			if (!remove)
			{
				return BlockReason.None;
			}
			if (IsGateLike(effect) && GatePolicy.Holds(facts))
			{
				return GatePolicy.HeldReason(facts);
			}
			if (!serverAllows)
			{
				return BlockReason.SetByServer;
			}
			return BlockReason.None;
		}

		public static TargetAction SceneAction(bool removes, bool active, bool ownedByCairn)
		{
			if (removes)
			{
				if (!active)
				{
					return TargetAction.None;
				}
				return TargetAction.Deactivate;
			}
			if (!(!active && ownedByCairn))
			{
				return TargetAction.None;
			}
			return TargetAction.Restore;
		}

		public static float SmokeAlpha(float alpha, bool removes, float strength = 1f)
		{
			if (!removes)
			{
				return alpha * strength;
			}
			return 0f;
		}

		public static float Strength(float strength, bool serverAllows, bool held, bool gateLike)
		{
			if (!serverAllows || (held && gateLike) || float.IsNaN(strength))
			{
				return 1f;
			}
			if (!(strength < 0f))
			{
				if (!(strength > 1f))
				{
					return strength;
				}
				return 1f;
			}
			return 0f;
		}
	}
	public enum TargetKind
	{
		EnvironmentChild,
		LocationChild,
		FogDensity,
		PostProcessingFog,
		PostProcessingAmbientOcclusion,
		MistEmitter,
		DistantFogEmitter,
		ParticleMist,
		SnowGlintShader,
		SmokeAlpha
	}
	public enum TargetSource
	{
		NoFogBruh,
		BetterFog
	}
	public sealed class VisibilityTarget
	{
		public VisibilityEffect Effect { get; }

		public TargetKind Kind { get; }

		public TargetSource Source { get; }

		public string? Path { get; }

		public string? LocationListPrefix { get; }

		internal VisibilityTarget(VisibilityEffect effect, TargetKind kind, TargetSource source, string? path = null, string? locationListPrefix = null)
		{
			Effect = effect;
			Kind = kind;
			Source = source;
			Path = path;
			LocationListPrefix = locationListPrefix;
		}

		public override string ToString()
		{
			return Effect.ToString() + ": " + Kind.ToString() + ((Path == null) ? "" : (" " + ((LocationListPrefix == null) ? "" : (LocationListPrefix + ":")) + Path));
		}
	}
	public static class VisibilityTargets
	{
		public const string EnvironmentRoot = "_GameMain/_Environment";

		public const string SnowGlintProperty = "_SnowGlintStrength";

		private static readonly IReadOnlyList<VisibilityTarget>[] ByEffect = Enum.GetValues(typeof(VisibilityEffect)).Cast<VisibilityEffect>().Select((Func<VisibilityEffect, IReadOnlyList<VisibilityTarget>>)((VisibilityEffect e) => All.Where((VisibilityTarget t) => t.Effect == e).ToList().AsReadOnly()))
			.ToArray();

		public static IReadOnlyList<VisibilityTarget> All { get; } = Array.AsReadOnly(new VisibilityTarget[23]
		{
			Hook(VisibilityEffect.DistanceFog, TargetKind.FogDensity),
			Env(VisibilityEffect.DistanceFog, "FollowPlayer/Mist"),
			Hook(VisibilityEffect.DistanceFog, TargetKind.PostProcessingFog),
			Env(VisibilityEffect.DistanceFog, "Distant_fog_planes"),
			Hook(VisibilityEffect.DistanceFog, TargetKind.DistantFogEmitter),
			Env(VisibilityEffect.GroundMist, "FollowPlayer/GroundMist"),
			Env(VisibilityEffect.FogClouds, "FollowPlayer/FogClouds"),
			Hook(VisibilityEffect.MistEmitters, TargetKind.MistEmitter),
			Env(VisibilityEffect.OceanMist, "OceanMist"),
			Loc(VisibilityEffect.MistlandsMist, "_LocationList_Mistlands", "environment_effects/FollowPlayer/Mistlands_Globalmist"),
			Hook(VisibilityEffect.ParticleMist, TargetKind.ParticleMist),
			Env(VisibilityEffect.CaveMist, "FollowPlayer/InteriorDust"),
			Loc(VisibilityEffect.CaveMist, "_LocationList_MountainCaves", "environment/followplayer/env_mountain_cave/mist"),
			Loc(VisibilityEffect.CaveMist, "_LocationList_MountainCaves", "environment/followplayer/env_mountain_cave_hildir/mist"),
			Env(VisibilityEffect.SnowstormFog, "FollowPlayer/SnowStorm"),
			Env(VisibilityEffect.SnowstormFog, "FollowPlayer/Blizzard"),
			Hook(VisibilityEffect.SnowGlint, TargetKind.SnowGlintShader),
			Loc(VisibilityEffect.AshlandsMist, "_LocationList_Ashlands", "environment_effects/FollowPlayer/Ashlands_Misty"),
			Loc(VisibilityEffect.AshlandsFader, "_LocationList_Ashlands", "environment_effects/FollowPlayer/Ashlands_FaderFX"),
			Loc(VisibilityEffect.DeepNorthMist, "_LocationList_DeepNorth", "environment_effects/FollowPlayer/DeepNorth_Misty"),
			Loc(VisibilityEffect.DeepNorthFader, "_LocationList_DeepNorth", "environment_effects/FollowPlayer/DeepNorth_FaderFX"),
			Hook(VisibilityEffect.AmbientOcclusion, TargetKind.PostProcessingAmbientOcclusion),
			Hook(VisibilityEffect.Smoke, TargetKind.SmokeAlpha, TargetSource.BetterFog)
		});

		private static VisibilityTarget Env(VisibilityEffect e, string path)
		{
			return new VisibilityTarget(e, TargetKind.EnvironmentChild, TargetSource.NoFogBruh, path);
		}

		private static VisibilityTarget Loc(VisibilityEffect e, string prefix, string path)
		{
			return new VisibilityTarget(e, TargetKind.LocationChild, TargetSource.NoFogBruh, path, prefix);
		}

		private static VisibilityTarget Hook(VisibilityEffect e, TargetKind kind, TargetSource source = TargetSource.NoFogBruh)
		{
			return new VisibilityTarget(e, kind, source);
		}

		public static IReadOnlyList<VisibilityTarget> Of(VisibilityEffect effect)
		{
			return ByEffect[(int)effect];
		}
	}
}
namespace ExtraPotions.Cairn.WorldTime
{
	public static class WorldClockRate
	{
		public static float ScaleDelta(float delta, float rate)
		{
			if (!(delta > 0f) || float.IsInfinity(delta) || float.IsNaN(rate) || float.IsInfinity(rate))
			{
				return delta;
			}
			rate = Math.Min(10f, Math.Max(0.1f, rate));
			double num = (double)delta * (double)rate;
			if (!(num <= 3.4028234663852886E+38))
			{
				return delta;
			}
			return (float)num;
		}
	}
}
namespace ExtraPotions.Cairn.Skill
{
	public static class SkillHash
	{
		public static int Of(string text)
		{
			if (text == null)
			{
				throw new ArgumentNullException("text");
			}
			int num = 5381;
			int num2 = num;
			for (int i = 0; i < text.Length && text[i] != 0; i += 2)
			{
				num = ((num << 5) + num) ^ text[i];
				if (i == text.Length - 1 || text[i + 1] == '\0')
				{
					break;
				}
				num2 = ((num2 << 5) + num2) ^ text[i + 1];
			}
			return num + num2 * 1566083941;
		}

		public static int CustomType(string identity)
		{
			return Of(identity) & 0x7FFFFFFF;
		}
	}
	public enum ExploreSource
	{
		Other,
		Natural,
		Vantage
	}
	public sealed class ExploreScope
	{
		public ExploreSource Current { get; private set; }

		public ExploreSource Enter(ExploreSource source)
		{
			ExploreSource current = Current;
			Current = source;
			return current;
		}

		public void Exit(ExploreSource previous)
		{
			Current = previous;
		}
	}
	public static class ExploreCells
	{
		public static int CountNew(int px, int py, float radius, float pixelSize, int textureSize, Func<int, bool> explored)
		{
			if (explored == null)
			{
				throw new ArgumentNullException("explored");
			}
			if (textureSize <= 0 || !(pixelSize > 0f) || float.IsInfinity(pixelSize) || float.IsNaN(radius) || float.IsInfinity(radius))
			{
				return 0;
			}
			int num = (int)Math.Ceiling(Math.Max(0f, radius) / pixelSize);
			long num2 = (long)num * (long)num;
			int num3 = 0;
			for (int i = Math.Max(0, py - num); i <= Math.Min(textureSize - 1, py + num); i++)
			{
				for (int j = Math.Max(0, px - num); j <= Math.Min(textureSize - 1, px + num); j++)
				{
					long num4 = j - px;
					long num5 = i - py;
					if (num4 * num4 + num5 * num5 <= num2 && !explored(i * textureSize + j))
					{
						num3++;
					}
				}
			}
			return num3;
		}
	}
	public sealed class DiscoveryRequests
	{
		public const float WindowSeconds = 30f;

		private readonly List<(string Name, int Type, float At)> pending = new List<(string, int, float)>();

		public void Record(string? pinName, int pinType, float now)
		{
			if (pinName != null)
			{
				Prune(now);
				pending.Add((pinName, pinType, now));
			}
		}

		public bool Natural(string? pinName, int pinType, float now)
		{
			if (pinName == null)
			{
				return false;
			}
			Prune(now);
			foreach (var item in pending)
			{
				if (item.Type == pinType && string.Equals(item.Name, pinName, StringComparison.Ordinal))
				{
					return true;
				}
			}
			return false;
		}

		public void Clear()
		{
			pending.Clear();
		}

		private void Prune(float now)
		{
			pending.RemoveAll(((string Name, int Type, float At) r) => float.IsNaN(now) || now - r.At > 30f || now < r.At - 30f);
		}
	}
	public static class ExplorationExperience
	{
		public static float Area(ExploreSource source, int newTexels, float texelMetres, SkillValues values)
		{
			if (source != ExploreSource.Other)
			{
				return ExplorationSkill.AreaExperience(newTexels, texelMetres, values);
			}
			return 0f;
		}

		public static float Discovery(bool pinAdded, bool natural, SkillValues values)
		{
			if (!(pinAdded && natural))
			{
				return 0f;
			}
			return ExplorationSkill.DiscoveryExperience(values);
		}

		public static float Biome(bool knownBefore, SkillValues values)
		{
			if (!knownBefore)
			{
				return ExplorationSkill.BiomeExperience(values);
			}
			return 0f;
		}
	}
	public readonly struct SkillValues
	{
		public static SkillValues Defaults => new SkillValues(CairnSettings.Skill.Enabled.Default, CairnSettings.Skill.ExperiencePerSquareKilometre.Default, CairnSettings.Skill.LocationDiscoveryExperience.Default, CairnSettings.Skill.NewBiomeExperience.Default, CairnSettings.Skill.LandRadiusAt100.Default, CairnSettings.Skill.WeatherPenaltyReductionAt100.Default, CairnSettings.Skill.NightPenaltyReductionAt100.Default, CairnSettings.Skill.VantageLevel.Default, CairnSettings.Skill.VantageCooldown.Default);

		public bool Enabled { get; }

		public float ExperiencePerSquareKilometre { get; }

		public float LocationDiscoveryExperience { get; }

		public float NewBiomeExperience { get; }

		public float LandRadiusAt100 { get; }

		public float WeatherPenaltyReductionAt100 { get; }

		public float NightPenaltyReductionAt100 { get; }

		public int VantageLevel { get; }

		public float VantageCooldown { get; }

		public SkillValues(bool enabled, float experiencePerSquareKilometre, float locationDiscoveryExperience, float newBiomeExperience, float landRadiusAt100, float weatherPenaltyReductionAt100, float nightPenaltyReductionAt100, int vantageLevel, float vantageCooldown)
		{
			Enabled = enabled;
			ExperiencePerSquareKilometre = experiencePerSquareKilometre;
			LocationDiscoveryExperience = locationDiscoveryExperience;
			NewBiomeExperience = newBiomeExperience;
			LandRadiusAt100 = landRadiusAt100;
			WeatherPenaltyReductionAt100 = weatherPenaltyReductionAt100;
			NightPenaltyReductionAt100 = nightPenaltyReductionAt100;
			VantageLevel = vantageLevel;
			VantageCooldown = vantageCooldown;
		}

		public SkillValues With(bool? enabled = null, int? vantageLevel = null)
		{
			return new SkillValues(enabled ?? Enabled, ExperiencePerSquareKilometre, LocationDiscoveryExperience, NewBiomeExperience, LandRadiusAt100, WeatherPenaltyReductionAt100, NightPenaltyReductionAt100, vantageLevel ?? VantageLevel, VantageCooldown);
		}
	}
	public static class ExplorationSkill
	{
		public const string SkillId = "meadworks_exploration";

		public const int GameType = 1828632269;

		public const string Name = "Exploration";

		public const string Description = "Uncovering the map. Widens your map radius on land and softens the loss to darkness and weather.";

		public const string TextKey = "skill_exploration";

		public const string IconPrefab = "piece_cartographytable";

		public const float VantageStillSpeed = 0.2f;

		public const float VantageStillSeconds = 3f;

		public const float VantageMinimumAltitude = 30f;

		public static float Share(float at100Percent, float level)
		{
			if (float.IsNaN(level) || float.IsNaN(at100Percent) || float.IsInfinity(at100Percent))
			{
				return 0f;
			}
			float num = Math.Min(100f, Math.Max(0f, level));
			return at100Percent / 100f * (num / 100f);
		}

		public static RadiusFactors Factors(float level, SkillValues values, float keelSeaFactor)
		{
			if (!values.Enabled)
			{
				return new RadiusFactors(keelSeaFactor, 1f, 0f, 0f);
			}
			return new RadiusFactors(keelSeaFactor, 1f + Share(values.LandRadiusAt100, level), Share(values.WeatherPenaltyReductionAt100, level), Share(values.NightPenaltyReductionAt100, level));
		}

		public static float AreaExperience(int newTexels, float texelMetres, SkillValues values)
		{
			if (!values.Enabled || newTexels <= 0 || !(texelMetres > 0f) || float.IsInfinity(texelMetres))
			{
				return 0f;
			}
			return (float)((double)newTexels * (double)texelMetres * (double)texelMetres / 1000000.0 * (double)values.ExperiencePerSquareKilometre);
		}

		public static float DiscoveryExperience(SkillValues values)
		{
			if (!values.Enabled)
			{
				return 0f;
			}
			return values.LocationDiscoveryExperience;
		}

		public static float BiomeExperience(SkillValues values)
		{
			if (!values.Enabled)
			{
				return 0f;
			}
			return values.NewBiomeExperience;
		}

		public static bool VantageUnlocked(float level, SkillValues values)
		{
			if (values.Enabled && values.VantageLevel <= 100 && !float.IsNaN(level))
			{
				return level >= (float)values.VantageLevel;
			}
			return false;
		}

		public static float VantageRadius(float currentRadius)
		{
			return currentRadius * 2f;
		}

		public static bool StandingStill(float speed, bool onGround)
		{
			if (onGround && !float.IsNaN(speed))
			{
				return speed <= 0.2f;
			}
			return false;
		}

		public static bool VantageResets(float speed, bool onGround, bool interior)
		{
			if (!interior)
			{
				return !StandingStill(speed, onGround);
			}
			return true;
		}

		public static float VantageBase(float current, float game)
		{
			if (current > 0f && !float.IsInfinity(current))
			{
				return current;
			}
			if (game > 0f && !float.IsInfinity(game))
			{
				return game;
			}
			return 0f;
		}
	}
	public sealed class VantageTracker
	{
		private float still;

		private float? lastFired;

		public bool Tick(float now, float deltaSeconds, bool moving, float altitude, float level, SkillValues values, bool radiusSteppedAside = false)
		{
			if (radiusSteppedAside || moving || float.IsNaN(deltaSeconds) || deltaSeconds < 0f)
			{
				still = 0f;
				return false;
			}
			still += deltaSeconds;
			if (still < 3f)
			{
				return false;
			}
			if (!ExplorationSkill.VantageUnlocked(level, values) || !(altitude >= 30f))
			{
				return false;
			}
			if (lastFired.HasValue && now - lastFired.Value < values.VantageCooldown)
			{
				return false;
			}
			lastFired = now;
			still = 0f;
			return true;
		}

		public void Reset()
		{
			still = 0f;
			lastFired = null;
		}
	}
}
namespace ExtraPotions.Cairn.Radius
{
	public static class SeaFactorSource
	{
		public const float MaximumFactor = 16f;

		public static float Pick(bool keelProvides, float keelFactor, bool grindstoneAvailable, bool aboard, float grindstoneFactor)
		{
			if (keelProvides && Valid(keelFactor) && keelFactor > 1f)
			{
				return keelFactor;
			}
			if (!grindstoneAvailable || !aboard)
			{
				return 1f;
			}
			if (!float.IsNaN(grindstoneFactor) && !float.IsInfinity(grindstoneFactor) && !(grindstoneFactor < 0f))
			{
				return grindstoneFactor;
			}
			return 1f;
		}

		private static bool Valid(float factor)
		{
			if (!float.IsNaN(factor) && !float.IsInfinity(factor) && factor > 0f)
			{
				return factor <= 16f;
			}
			return false;
		}
	}
	public static class ExploreCurrentValue
	{
		public const float MaximumRadius = 10000f;

		public static float Of(bool computed, float radius)
		{
			if (!computed || float.IsNaN(radius) || float.IsInfinity(radius) || radius < 0f)
			{
				return -1f;
			}
			return Math.Min(10000f, radius);
		}
	}
	public readonly struct Rgb
	{
		public float R { get; }

		public float G { get; }

		public float B { get; }

		public float Magnitude => (float)Math.Sqrt(R * R + G * G + B * B);

		public Rgb(float r, float g, float b)
		{
			R = r;
			G = g;
			B = b;
		}
	}
	public enum RadiusBiome
	{
		Other,
		Meadows,
		BlackForest,
		Plains
	}
	public sealed class RadiusInputs
	{
		public bool Interior { get; set; }

		public bool ShipNearby { get; set; }

		public Rgb DirectionalLight { get; set; }

		public Rgb AmbientLight { get; set; }

		public float FogDensity { get; set; }

		public IReadOnlyList<string> ParticleSystems { get; set; } = Array.Empty<string>();

		public float Altitude { get; set; }

		public RadiusBiome Biome { get; set; }

		public bool InForest { get; set; }

		public float ForestFactor { get; set; } = 1f;
	}
	public readonly struct RadiusValues
	{
		public static RadiusValues Defaults => new RadiusValues(CairnSettings.Radius.MinimumRadius.Default, CairnSettings.Radius.MaximumRadius.Default, CairnSettings.Radius.LandExploreRadius.Default, CairnSettings.Radius.SeaExploreRadius.Default, CairnSettings.Radius.AltitudeRadiusBonus.Default, CairnSettings.Radius.ForestRadiusPenalty.Default, CairnSettings.Radius.DaylightRadiusScale.Default, CairnSettings.Radius.WeatherRadiusScale.Default);

		public float Minimum { get; }

		public float Maximum { get; }

		public float Land { get; }

		public float Sea { get; }

		public float AltitudeBonus { get; }

		public float ForestPenalty { get; }

		public float DaylightScale { get; }

		public float WeatherScale { get; }

		public RadiusValues(float minimum, float maximum, float land, float sea, float altitudeBonus, float forestPenalty, float daylightScale, float weatherScale)
		{
			Minimum = minimum;
			Maximum = maximum;
			Land = land;
			Sea = sea;
			AltitudeBonus = altitudeBonus;
			ForestPenalty = forestPenalty;
			DaylightScale = daylightScale;
			WeatherScale = weatherScale;
		}

		public RadiusValues With(float? minimum = null, float? maximum = null, float? land = null, float? sea = null)
		{
			return new RadiusValues(minimum ?? Minimum, maximum ?? Maximum, land ?? Land, sea ?? Sea, AltitudeBonus, ForestPenalty, DaylightScale, WeatherScale);
		}

		public RadiusValues Held()
		{
			float? maximum = Math.Min(Maximum, 2000f);
			float? land = Math.Min(Land, 200f);
			float? sea = Math.Min(Sea, 300f);
			return With(null, maximum, land, sea);
		}
	}
	public readonly struct RadiusFactors
	{
		public static RadiusFactors None => new RadiusFactors(1f, 1f, 0f, 0f);

		public float Sea { get; }

		public float Land { get; }

		public float WeatherReduction { get; }

		public float NightReduction { get; }

		public RadiusFactors(float sea, float land, float weatherReduction, float nightReduction)
		{
			Sea = Finite(sea, 1f, 0f, float.MaxValue);
			Land = Finite(land, 1f, 0f, float.MaxValue);
			WeatherReduction = Finite(weatherReduction, 0f, 0f, 1f);
			NightReduction = Finite(nightReduction, 0f, 0f, 1f);
		}

		internal static float Finite(float value, float fallback, float min, float max)
		{
			if (!float.IsNaN(value) && !float.IsInfinity(value))
			{
				return Math.Min(max, Math.Max(min, value));
			}
			return fallback;
		}
	}
	public readonly struct RadiusResult
	{
		public float Radius { get; }

		public float Base { get; }

		public float Multiplier { get; }

		public float LightTerm { get; }

		public float WeatherTerm { get; }

		public float AltitudeTerm { get; }

		public float LocationTerm { get; }

		public float Factor { get; }

		public RadiusResult(float radius, float baseRadius, float multiplier, float light, float weather, float altitude, float location, float factor)
		{
			Radius = radius;
			Base = baseRadius;
			Multiplier = multiplier;
			LightTerm = light;
			WeatherTerm = weather;
			AltitudeTerm = altitude;
			LocationTerm = location;
			Factor = factor;
		}
	}
	public static class RadiusModel
	{
		public const float ShipShareRange = 21f;

		public static RadiusResult Compute(RadiusInputs inputs, RadiusValues values, RadiusFactors factors)
		{
			if (inputs == null)
			{
				throw new ArgumentNullException("inputs");
			}
			float num = Clamp(values.Maximum, 0f, 10000f);
			float min = Math.Min(Clamp(values.Minimum, 0f, 10000f), num);
			float num2 = Clamp(values.Land, 0f, 2000f);
			float num3 = Clamp(values.Sea, 0f, 2000f);
			float num4 = Clamp(values.AltitudeBonus, 0f, 2f);
			float forestPenalty = Clamp(values.ForestPenalty, 0f, 1f);
			float num5 = Clamp(values.DaylightScale, 0f, 1f);
			float num6 = Clamp(values.WeatherScale, 0f, 1f);
			if (inputs.Interior)
			{
				return new RadiusResult(Math.Max(num2 * 0.2f, 10f), num2, 1f, 0f, 0f, 0f, 0f, 1f);
			}
			float num7 = (inputs.ShipNearby ? num3 : num2);
			float num8 = 1f;
			float num9 = Math.Max(inputs.DirectionalLight.Magnitude, inputs.AmbientLight.Magnitude);
			if (!IsFinite(num9))
			{
				num9 = 1f;
			}
			float num10 = (num9 - 1f) * num5;
			if (num10 < 0f)
			{
				num10 *= 1f - factors.NightReduction;
			}
			num8 += num10;
			float num11 = 0f;
			foreach (string item in inputs.ParticleSystems ?? Array.Empty<string>())
			{
				if (string.Equals(item, "Mist", StringComparison.OrdinalIgnoreCase))
				{
					num11 += 0.5f;
				}
				if (string.Equals(item, "SnowStorm", StringComparison.OrdinalIgnoreCase))
				{
					num11 += 0.7f * num9;
				}
			}
			float num12 = (0f - Clamp((IsFinite(inputs.FogDensity) ? inputs.FogDensity : 0f) * 10f + num11, 0f, 1.5f)) * num6 * (1f - factors.WeatherReduction);
			num8 += num12;
			float num13 = Clamp(IsFinite(inputs.Altitude) ? inputs.Altitude : 0f, 0f, 400f) / 100f * Math.Max(0.05f, 1f - num11);
			float num14 = num13 * num4;
			num8 += num14;
			float num15 = Location(inputs, num13, num4, forestPenalty, num5);
			num8 += num15;
			if (num8 > 5f)
			{
				num8 = 5f;
			}
			if (num8 < 0.2f)
			{
				num8 = 0.2f;
			}
			float num16 = (inputs.ShipNearby ? factors.Sea : factors.Land);
			return new RadiusResult(Clamp(num7 * num8 * num16, min, num), num7, num8, num10, num12, num14, num15, num16);
		}

		public static float Disabled(float gameRadius, bool shipNearby, RadiusFactors factors)
		{
			return ((IsFinite(gameRadius) && gameRadius > 0f) ? gameRadius : 0f) * (shipNearby ? factors.Sea : factors.Land);
		}

		private static float Location(RadiusInputs inputs, float altitude, float altitudeBonus, float forestPenalty, float daylightScale)
		{
			float num = forestPenalty + altitude * altitudeBonus * forestPenalty;
			switch (inputs.Biome)
			{
			case RadiusBiome.BlackForest:
				return 0f - num - 0.25f * daylightScale;
			case RadiusBiome.Meadows:
				if (!inputs.InForest)
				{
					return 0f;
				}
				return 0f - num;
			case RadiusBiome.Plains:
				return ((inputs.ForestFactor < 0.8f) ? (0f - num) : 0f) + 0.1f * daylightScale;
			default:
				return 0f;
			}
		}

		private static bool IsFinite(float value)
		{
			if (!float.IsNaN(value))
			{
				return !float.IsInfinity(value);
			}
			return false;
		}

		private static float Clamp(float value, float min, float max)
		{
			if (!IsFinite(value))
			{
				return min;
			}
			return Math.Min(max, Math.Max(min, value));
		}
	}
}
namespace ExtraPotions.Cairn.Localization
{
	public readonly struct TextKey
	{
		public string Key { get; }

		public int Arguments { get; }

		public TextKey(string key, int arguments)
		{
			Key = key;
			Arguments = arguments;
		}

		public override string ToString()
		{
			return Key;
		}
	}
	public static class CairnTextKeys
	{
		public const string HeldNotice = "held_notice";

		public const string SkillName = "skill_exploration";

		public const string SkillDescription = "skill_exploration_description";

		public const string Vantage = "vantage";

		public const string HudDay = "hud_day";

		public const string SquareComfort = "square_comfort";

		public const string SquareRested = "square_rested";

		public const string SquareNotRested = "square_not_rested";

		public const string HudHeading = "hud_heading";

		public const string HudForecast = "hud_forecast";

		public const string HudForecastWind = "hud_forecast_wind";

		public const string RadiusLine = "radius_line";

		public const string RadiusInputs = "radius_inputs";

		public const string ImportDone = "import_done";

		public const string TidyPinsDescription = "tidy_pins_description";

		public const string TempestWarning = "tempest_warning";

		public const string TempestClearing = "tempest_clearing";

		public const string TempestNotice = "tempest_notice";

		public static readonly IReadOnlyList<string> PinTypes = Array.AsReadOnly(new string[18]
		{
			"Icon0", "Icon1", "Icon2", "Icon3", "Icon4", "Death", "Bed", "Shout", "None", "Boss",
			"Player", "RandomEvent", "Ping", "EventArea", "Hildir1", "Hildir2", "Hildir3", "Memorial"
		});

		private static readonly string[] Points = new string[8] { "N", "NE", "E", "SE", "S", "SW", "W", "NW" };

		public static IReadOnlyList<TextKey> All { get; } = Array.AsReadOnly(new TextKey[60]
		{
			new TextKey("held_notice", 0),
			new TextKey("skill_exploration", 0),
			new TextKey("skill_exploration_description", 0),
			new TextKey("vantage", 0),
			new TextKey("hud_day", 1),
			new TextKey("square_comfort", 1),
			new TextKey("square_rested", 1),
			new TextKey("square_not_rested", 0),
			new TextKey("hud_heading", 2),
			new TextKey("hud_forecast", 2),
			new TextKey("hud_forecast_wind", 3),
			new TextKey("radius_line", 1),
			new TextKey("radius_inputs", 7),
			new TextKey("import_done", 2),
			new TextKey("tidy_pins_description", 0),
			new TextKey("tempest_warning", 2),
			new TextKey("tempest_clearing", 1),
			new TextKey("tempest_notice", 1),
			new TextKey(TempestEvent(TempestKind.Blizzard), 0),
			new TextKey(TempestEvent(TempestKind.Thunderstorm), 0),
			new TextKey(TempestEvent(TempestKind.LightningStorm), 0),
			new TextKey(TempestEvent(TempestKind.DenseFog), 0),
			new TextKey(TempestEvent(TempestKind.AshStorm), 0),
			new TextKey(TempestEvent(TempestKind.MeteorShower), 0),
			new TextKey("ui_close", 0),
			new TextKey("ui_on", 0),
			new TextKey("ui_off", 0),
			new TextKey("ui_tab_markers", 0),
			new TextKey("ui_tab_hud", 0),
			new TextKey("ui_tab_compass", 0),
			new TextKey("ui_tab_visibility", 0),
			new TextKey("ui_tab_map", 0),
			new TextKey("ui_markers_hint", 0),
			new TextKey("ui_shown_by_type", 1),
			new TextKey("ui_map_cursor", 0),
			new TextKey("ui_help_close", 0),
			new TextKey("ui_help_tab_markers", 0),
			new TextKey("ui_help_tab_hud", 0),
			new TextKey("ui_help_tab_compass", 0),
			new TextKey("ui_help_tab_visibility", 0),
			new TextKey("ui_help_tab_map", 0),
			new TextKey("ui_help_map_cursor", 0),
			new TextKey("ui_help_marker_type", 0),
			new TextKey("ui_help_marker_pin", 0),
			new TextKey("ui_help_marker_map", 0),
			new TextKey("ui_help_decrease", 0),
			new TextKey("ui_help_increase", 0),
			new TextKey("ui_menu_hud_settings", 0),
			new TextKey("ui_menu_markers", 0),
			new TextKey("ui_menu_hud_hide", 0),
			new TextKey("ui_menu_hud_show", 0),
			new TextKey("sleep_sleeping", 2),
			new TextKey("sleep_boost", 1),
			new TextKey("sleep_skip", 1),
			new TextKey("setting_remove", 1),
			new TextKey("setting_allow_removing", 1),
			new TextKey("help_remove", 1),
			new TextKey("help_allow_removing", 1),
			new TextKey(Setting(CairnSettings.Radius.ShowRadiusInputs), 0),
			new TextKey(SettingHelp(CairnSettings.Radius.ShowRadiusInputs), 0)
		}.Concat(from CairnModule m in Enum.GetValues(typeof(CairnModule))
			select new TextKey(StepAsideNotice.KeyOf(m), 1)).Concat(from WeatherCategory c in Enum.GetValues(typeof(WeatherCategory))
			select new TextKey(Weather(c), 0)).Concat(Points.Select((string p) => new TextKey(CompassPoint(p), 0)))
			.Concat(PinTypes.Select((string t) => new TextKey(PinType(t), 0)))
			.Concat(from s in CairnSettings.All
				where !s.Hidden && s.Section != "2 - Visibility" && s.Section != "3 - Visibility Server"
				select new TextKey(Setting(s), 0))
			.Concat(from s in CairnSettings.All
				where !s.Hidden && s.Section != "2 - Visibility" && s.Section != "3 - Visibility Server" && s != CairnSettings.Map.TidyPins
				select new TextKey(SettingHelp(s), 0))
			.Concat(from VisibilityEffect e in Enum.GetValues(typeof(VisibilityEffect))
				select new TextKey(Effect(e), 0))
			.ToArray());

		public static string TempestEvent(TempestKind kind)
		{
			return TempestToken(ExtraPotions.Cairn.Hud.TempestWarning.Token(kind) ?? kind.ToString().ToLowerInvariant());
		}

		public static string TempestToken(string token)
		{
			return "tempest_" + token;
		}

		public static string Weather(WeatherCategory category)
		{
			return "weather_" + category.ToString().ToLowerInvariant();
		}

		public static string CompassPoint(string point)
		{
			return "compass_" + point.ToLowerInvariant();
		}

		public static string Setting(CairnSetting setting)
		{
			return "setting_" + setting.Section[0] + "_" + setting.Key.ToLowerInvariant().Replace(' ', '_');
		}

		public static string Effect(VisibilityEffect effect)
		{
			return "effect_" + effect.ToString().ToLowerInvariant();
		}

		public static string SettingHelp(CairnSetting setting)
		{
			return "help_" + Setting(setting);
		}

		public static string PinType(string type)
		{
			return "pin_type_" + type.ToLowerInvariant();
		}
	}
}
namespace ExtraPotions.Cairn.Integration
{
	public enum HookKind
	{
		Method,
		Field
	}
	public enum HookStatus
	{
		Wired,
		Pending
	}
	public sealed class HookTarget
	{
		public string Module { get; }

		public string Type { get; }

		public string Member { get; }

		public HookKind Kind { get; }

		public string Signature { get; }

		public HookStatus Status { get; }

		public string Purpose { get; }

		internal HookTarget(string module, string type, string member, HookKind kind, string signature, HookStatus status, string purpose)
		{
			Module = module;
			Type = type;
			Member = member;
			Kind = kind;
			Signature = signature;
			Status = status;
			Purpose = purpose;
		}

		public override string ToString()
		{
			return Type + "." + Member + ((Kind == HookKind.Method) ? ("(" + Signature + ")") : (" : " + Signature));
		}
	}
	public static class HookTargets
	{
		public static IReadOnlyList<HookTarget> PostProcessing { get; } = Array.AsReadOnly(new HookTarget[3]
		{
			M("Visibility", "PostProcessingBehaviour", "OnPreRender", "", HookStatus.Wired, "native post-processing command-buffer execution"),
			M("Visibility", "PostProcessingBehaviour", "TryExecuteCommandBuffer", "PostProcessingComponentCommandBuffer`1<!!0>", HookStatus.Wired, "preserved native execution when removal is off"),
			M("Visibility", "PostProcessingBehaviour", "RemoveCommandBuffer", "", HookStatus.Wired, "NoFogBruh fog and ambient command-buffer removal")
		});

		public static IReadOnlyList<HookTarget> All { get; } = Array.AsReadOnly(new HookTarget[85]
		{
			M("Radius", "Minimap", "UpdateExplore", "Single,Player", HookStatus.Wired, "transpiler replaces the m_exploreRadius read with Cairn's radius (A7); prefix and finalizer mark the natural explore scope for Exploration experience (CA04b)"),
			F("Radius", "Minimap", "m_exploreRadius", "Single", HookStatus.Wired, "the field the transpiler replaces; also the radius-off base"),
			M("Radius", "Character", "InInterior", "", HookStatus.Wired, "dungeon radius (Pathfinder interior rule)"),
			M("Radius", "Player", "GetPlayersInRange", "Vector3,Single,List`1<Player>", HookStatus.Wired, "players within 21 m"),
			M("Radius", "Player", "IsAttachedToShip", "", HookStatus.Wired, "sea radius"),
			M("Radius", "Player", "GetCurrentBiome", "", HookStatus.Wired, "location term"),
			M("Radius", "WorldGenerator", "InForest", "Vector3", HookStatus.Wired, "Meadows forest"),
			M("Radius", "WorldGenerator", "GetForestFactor", "Vector3", HookStatus.Wired, "Plains forest"),
			F("Radius", "ZoneSystem", "m_waterLevel", "Single", HookStatus.Wired, "altitude"),
			F("Radius", "EnvMan", "m_dirLight", "Light", HookStatus.Wired, "daylight term"),
			M("Radius", "EnvMan", "GetCurrentEnvironment", "", HookStatus.Wired, "weather particle systems"),
			F("Radius", "EnvSetup", "m_psystems", "GameObject[]", HookStatus.Wired, "Mist and SnowStorm names"),
			M("Radius", "Ship", "GetLocalShip", "", HookStatus.Wired, "GrindstoneSkills Sailing factor only while aboard"),
			M("Visibility", "EnvMan", "SetEnv", "EnvSetup,Single,Single,Single,Single,Single", HookStatus.Wired, "game fog density captured, distance fog removed, scene targets applied"),
			M("Visibility", "EnvMan", "Update", "", HookStatus.Wired, "snow glint removed each frame"),
			M("Visibility", "EnvMan", "SetParticleArrayEnabled", "GameObject[],Boolean", HookStatus.Wired, "mist emitters and distant fog emitters"),
			M("Visibility", "ParticleMist", "Update", "", HookStatus.Wired, "particle mist skipped and cleared"),
			F("Visibility", "ParticleMist", "m_ps", "ParticleSystem", HookStatus.Wired, "particle mist system"),
			M("Visibility", "DistantFogEmitter", "Update", "", HookStatus.Wired, "distant fog stops emitting"),
			M("Visibility", "DistantFogEmitter", "SetEmit", "Boolean", HookStatus.Wired, "distant fog stops emitting"),
			M("Visibility", "Smoke", "GetAlpha", "", HookStatus.Wired, "smoke alpha 0 or scaled by Smoke Strength (BetterFog hook)"),
			F("Visibility", "DistantFogEmitter", "m_psystems", "ParticleSystem[]", HookStatus.Wired, "fog bank systems graded by Mist Strength"),
			F("Visibility", "EnvMan", "m_currentPSystems", "GameObject[]", HookStatus.Wired, "weather fog-like systems graded by Mist Strength"),
			M("Visibility", "LocationList", "GetAllLocationLists", "", HookStatus.Wired, "biome location lists for Mistlands, cave, Ashlands and Deep North mist"),
			M("Hud", "EnvMan", "GetDayFraction", "", HookStatus.Wired, "clock time (CA06b)"),
			M("Hud", "EnvMan", "GetCurrentDay", "", HookStatus.Wired, "day number (CA06b)"),
			M("Hud", "EnvMan", "IsNight", "", HookStatus.Wired, "night fog density for the weather fallback (CA06b)"),
			F("Hud", "EnvSetup", "m_name", "String", HookStatus.Wired, "weather category by environment name (CA06b)"),
			F("Hud", "EnvSetup", "m_isWet", "Boolean", HookStatus.Wired, "rain fallback for unknown environments (CA06b)"),
			F("Hud", "EnvSetup", "m_fogDensityDay", "Single", HookStatus.Wired, "fog fallback for unknown environments (CA06b)"),
			F("Hud", "EnvSetup", "m_fogDensityNight", "Single", HookStatus.Wired, "fog fallback for unknown environments (CA06b)"),
			M("Hud", "Hud", "IsUserHidden", "", HookStatus.Wired, "hides with the game's HUD toggle (CA06b)"),
			M("Hud", "Minimap", "IsOpen", "", HookStatus.Wired, "hidden on the large map (CA06b)"),
			M("Hud", "Menu", "UpdateNavigation", "", HookStatus.Wired, "owned pause-menu entry navigation (CA07b)"),
			F("Hud", "Menu", "menuEntriesParent", "RectTransform", HookStatus.Wired, "owned settings entry parent (CA07b)"),
			F("Hud", "Menu", "m_settingsButton", "Button", HookStatus.Wired, "native kit menu-button template (CA07b)"),
			M("Skill", "Minimap", "Explore", "Vector3,Single", HookStatus.Wired, "prefix counts newly explored texels inside the natural or Vantage scope; Vantage calls it (CA04b)"),
			F("Skill", "Minimap", "m_explored", "BitArray", HookStatus.Wired, "the local player's explored texels, read before an explore"),
			M("Skill", "Minimap", "WorldToPixel", "Vector3,Int32&,Int32&", HookStatus.Wired, "explore centre texel"),
			F("Skill", "Minimap", "m_pixelSize", "Single", HookStatus.Wired, "texel size in meters for area experience"),
			F("Skill", "Minimap", "m_textureSize", "Int32", HookStatus.Wired, "explored map width in texels"),
			M("Skill", "Minimap", "DiscoverLocation", "Vector3,Minimap/PinType,String,Boolean", HookStatus.Wired, "postfix: discovery experience when a new pin was added inside a natural response (CA04b)"),
			M("Skill", "Vegvisir", "Interact", "Humanoid,Boolean,Boolean", HookStatus.Wired, "natural discovery interaction scope"),
			M("Skill", "RuneStone", "Interact", "Humanoid,Boolean,Boolean", HookStatus.Wired, "natural discovery interaction scope"),
			M("Skill", "Game", "DiscoverClosestLocation", "String,Vector3,String,Int32,Boolean,Boolean", HookStatus.Wired, "records the natural request sent to the server"),
			M("Skill", "Game", "RPC_DiscoverLocationResponse", "Int64,String,Int32,Vector3,Boolean", HookStatus.Wired, "natural response scope around the pin it adds"),
			M("Skill", "Player", "AddKnownBiome", "BiomeSector", HookStatus.Wired, "prefix reads IsBiomeKnown, postfix pays new biome experience (CA04b)"),
			M("Skill", "Player", "IsBiomeKnown", "BiomeSector", HookStatus.Wired, "biome known before AddKnownBiome"),
			M("Skill", "Character", "IsOnGround", "", HookStatus.Wired, "Vantage stands on the ground"),
			M("Skill", "Character", "GetVelocity", "", HookStatus.Wired, "Vantage stands still"),
			M("Skill", "Player", "Message", "MessageHud/MessageType,String,Int32,Sprite,Boolean", HookStatus.Wired, "Vantage notice"),
			M("Skill", "ZNetScene", "GetPrefab", "String", HookStatus.Wired, "map table prefab for the skill icon"),
			F("Skill", "Piece", "m_icon", "Sprite", HookStatus.Wired, "map table icon, read at run time (D1)"),
			F("Markers", "Minimap", "m_pins", "List`1<Minimap/PinData>", HookStatus.Wired, "the player's map pins for the Markers map (CA07a)"),
			M("Markers", "Minimap", "GetSprite", "Minimap/PinType", HookStatus.Wired, "the game's own pin icons on the Markers map"),
			M("Markers", "Minimap", "WorldToMapPoint", "Vector3,Single&,Single&", HookStatus.Wired, "pin positions on the Markers map"),
			F("Markers", "Minimap", "m_mapTexture", "Texture2D", HookStatus.Wired, "Markers map image, the game's own at runtime"),
			F("Markers", "Minimap", "m_exploredOthers", "BitArray", HookStatus.Wired, "Markers map fog of war: shared map data"),
			F("Markers", "Minimap", "m_showSharedMapData", "Boolean", HookStatus.Wired, "shared map data shown, as on the large map"),
			F("Markers", "Minimap", "m_heightTexture", "Texture2D", HookStatus.Wired, "Markers map water below the water level"),
			F("Markers", "Minimap", "m_meadowsColor", "Color", HookStatus.Wired, "biome tint in the game's map texture"),
			F("Markers", "Minimap", "m_blackforestColor", "Color", HookStatus.Wired, "biome tint in the game's map texture"),
			F("Markers", "Minimap", "m_swampColor", "Color", HookStatus.Wired, "biome tint in the game's map texture"),
			F("Markers", "Minimap", "m_mountainColor", "Color", HookStatus.Wired, "biome tint in the game's map texture"),
			F("Markers", "Minimap", "m_heathColor", "Color", HookStatus.Wired, "biome tint in the game's map texture (plains)"),
			F("Markers", "Minimap", "m_mistlandsColor", "Color", HookStatus.Wired, "biome tint in the game's map texture"),
			F("Markers", "Minimap", "m_ashlandsColor", "Color", HookStatus.Wired, "biome tint in the game's map texture"),
			F("Markers", "Minimap", "m_deepnorthColor", "Color", HookStatus.Wired, "biome tint in the game's map texture"),
			F("Markers", "Minimap/PinData", "m_type", "Minimap/PinType", HookStatus.Wired, "pin type, the marker type entry; Tidy Pins keeps player, ping and shout pins at the game's size and opacity"),
			F("Markers", "Minimap/PinData", "m_pos", "Vector3", HookStatus.Wired, "pin position, the single marker entry"),
			F("Markers", "Minimap/PinData", "m_name", "String", HookStatus.Wired, "pin label"),
			F("Markers", "Minimap/PinData", "m_icon", "Sprite", HookStatus.Wired, "the pin's own icon (location pins such as the start temple have type None)"),
			F("Markers", "Minimap", "m_pinSizeLarge", "Single", HookStatus.Wired, "the large map's pin size, matched by the Markers map's pins"),
			F("Markers", "Player", "m_customData", "Dictionary`2<String,String>", HookStatus.Wired, "per-world marker choices in character data (C4)"),
			M("Markers", "ZNet", "GetWorldUID", "", HookStatus.Wired, "the world the marker choices belong to"),
			M("Import", "ZNet", "GetWorld", "", HookStatus.Wired, "match imported world names to the current world"),
			F("Import", "World", "m_name", "String", HookStatus.Wired, "source marker world name"),
			M("Import", "Player", "GetPlayerName", "", HookStatus.Wired, "source marker character name"),
			M("TidyPins", "Minimap", "Update", "", HookStatus.Wired, "restore owned visuals before native refresh, then apply local tidy-pin presentation"),
			F("TidyPins", "Minimap", "m_mode", "Minimap/MapMode", HookStatus.Wired, "names are hovered only on the large map"),
			F("TidyPins", "Minimap/PinData", "m_uiElement", "RectTransform", HookStatus.Wired, "visible icon scale and mouse/pad hit area"),
			F("TidyPins", "Minimap/PinData", "m_iconElement", "Image", HookStatus.Wired, "fade checked pin icons without changing pin data"),
			F("TidyPins", "Minimap/PinData", "m_checkedElement", "GameObject", HookStatus.Wired, "fade the checked indicator alongside its icon"),
			F("TidyPins", "Minimap/PinData", "m_checked", "Boolean", HookStatus.Wired, "read-only crossed-out state"),
			F("TidyPins", "Minimap/PinData", "m_worldSize", "Single", HookStatus.Wired, "leave event-area circles at their true world size")
		});

		private static HookTarget M(string module, string type, string member, string parameters, HookStatus status, string purpose)
		{
			return new HookTarget(module, type, member, HookKind.Method, parameters, status, purpose);
		}

		private static HookTarget F(string module, string type, string member, string fieldType, HookStatus status, string purpose)
		{
			return new HookTarget(module, type, member, HookKind.Field, fieldType, status, purpose);
		}
	}
	public enum CairnModule
	{
		Radius,
		Visibility,
		Hud
	}
	public sealed class ModuleSource
	{
		public string Guid { get; }

		public string Name { get; }

		internal ModuleSource(string guid, string name)
		{
			Guid = guid;
			Name = name;
		}
	}
	public sealed class SourceSwitches
	{
		public static SourceSwitches Unknown => new SourceSwitches();

		public bool? TimeWeatherHudEnabled { get; set; }

		public static SourceSwitches Read(string? timeWeatherHudConfig)
		{
			SourceSwitches sourceSwitches = new SourceSwitches();
			if (timeWeatherHudConfig != null)
			{
				SourceEntry sourceEntry = SourceConfig.Parse(timeWeatherHudConfig).FirstOrDefault((SourceEntry e) => e.Section == "General" && e.Key == "Enabled");
				sourceSwitches.TimeWeatherHudEnabled = sourceEntry.Key == null || !string.Equals(sourceEntry.Value, "false", StringComparison.OrdinalIgnoreCase);
			}
			return sourceSwitches;
		}
	}
	public readonly struct StepAsideNotice
	{
		public CairnModule Module { get; }

		public string SourceNames { get; }

		public string Key => KeyOf(Module);

		public StepAsideNotice(CairnModule module, string sourceNames)
		{
			Module = module;
			SourceNames = sourceNames;
		}

		public static string KeyOf(CairnModule module)
		{
			return "step_aside_" + module.ToString().ToLowerInvariant();
		}
	}
	public sealed class StepAsideDecision
	{
		private readonly Dictionary<CairnModule, List<ModuleSource>> aside;

		public bool Any => aside.Count > 0;

		public IReadOnlyList<StepAsideNotice> Notices { get; }

		internal StepAsideDecision(Dictionary<CairnModule, List<ModuleSource>> aside)
		{
			this.aside = aside;
			Notices = (from p in aside
				orderby p.Key
				select new StepAsideNotice(p.Key, string.Join(" and ", p.Value.Select((ModuleSource s) => s.Name)))).ToList();
		}

		public bool SteppedAside(CairnModule module)
		{
			return aside.ContainsKey(module);
		}

		public IReadOnlyList<ModuleSource> SourcesOf(CairnModule module)
		{
			if (!aside.TryGetValue(module, out List<ModuleSource> value))
			{
				return Array.Empty<ModuleSource>();
			}
			return value;
		}
	}
	public static class ModuleStepAside
	{
		public static readonly ModuleSource Pathfinder = new ModuleSource("dev.crystal.pathfinder", "Pathfinder");

		public static readonly ModuleSource NoFogBruh = new ModuleSource("vapok.mods.nofogbruh", "NoFogBruh");

		public static readonly ModuleSource BetterFog = new ModuleSource("JevMods.BetterFog", "BetterFog");

		public static readonly ModuleSource TimeWeatherHud = new ModuleSource("lazly.valheim.timeweatherhud", "TimeWeatherHud");

		public static IReadOnlyList<ModuleSource> Sources { get; } = Array.AsReadOnly(new ModuleSource[4] { Pathfinder, NoFogBruh, BetterFog, TimeWeatherHud });

		public static StepAsideDecision Decide(IEnumerable<string> installedGuids, SourceSwitches switches)
		{
			if (installedGuids == null)
			{
				throw new ArgumentNullException("installedGuids");
			}
			SourceSwitches sourceSwitches = switches ?? SourceSwitches.Unknown;
			HashSet<string> installed = new HashSet<string>(installedGuids.Where((string g) => g != null), StringComparer.Ordinal);
			Dictionary<CairnModule, List<ModuleSource>> aside = new Dictionary<CairnModule, List<ModuleSource>>();
			Add(Pathfinder, CairnModule.Radius, acts: true);
			Add(NoFogBruh, CairnModule.Visibility, acts: true);
			Add(BetterFog, CairnModule.Visibility, acts: true);
			Add(TimeWeatherHud, CairnModule.Hud, sourceSwitches.TimeWeatherHudEnabled != false);
			return new StepAsideDecision(aside);
			void Add(ModuleSource source, CairnModule module, bool acts)
			{
				if (acts && installed.Contains(source.Guid))
				{
					if (!aside.TryGetValue(module, out List<ModuleSource> value))
					{
						value = (aside[module] = new List<ModuleSource>());
					}
					value.Add(source);
				}
			}
		}
	}
}
namespace ExtraPotions.Cairn.Hud
{
	public static class Clock
	{
		public static (int Hour, int Minute) Parts(float dayFraction)
		{
			double num = ((float.IsNaN(dayFraction) || float.IsInfinity(dayFraction)) ? 0.0 : ((double)dayFraction - Math.Floor(dayFraction))) * 24.0;
			int num2 = (int)Math.Floor(num);
			int val = (int)Math.Floor((num - (double)num2) * 60.0);
			return (Hour: Math.Min(23, Math.Max(0, num2)), Minute: Math.Min(59, Math.Max(0, val)));
		}

		public static string Text(float dayFraction, bool use24Hour)
		{
			var (num, num2) = Parts(dayFraction);
			if (use24Hour)
			{
				return num.ToString("00", CultureInfo.InvariantCulture) + ":" + num2.ToString("00", CultureInfo.InvariantCulture);
			}
			return ((num % 12 == 0) ? 12 : (num % 12)).ToString(CultureInfo.InvariantCulture) + ":" + num2.ToString("00", CultureInfo.InvariantCulture) + ((num < 12) ? " AM" : " PM");
		}
	}
	public static class ColumnSquares
	{
		public const int ComfortRank = 500;

		public const string ComfortId = "cairn_comfort";

		public static string Comfort(int level, float restedSeconds)
		{
			string text = Rested(restedSeconds);
			string text2 = Math.Max(0, level).ToString(CultureInfo.InvariantCulture);
			if (text.Length != 0)
			{
				return text2 + "\n" + text;
			}
			return text2;
		}

		public static string Rested(float seconds)
		{
			if (float.IsNaN(seconds) || float.IsInfinity(seconds) || seconds <= 0f)
			{
				return "";
			}
			int num = (int)Math.Ceiling(seconds);
			return (num / 60).ToString(CultureInfo.InvariantCulture) + ":" + (num % 60).ToString("00", CultureInfo.InvariantCulture);
		}
	}
	public readonly struct MarkerPin
	{
		public string Id { get; }

		public float X { get; }

		public float Z { get; }

		public MarkerPin(string id, float x, float z)
		{
			Id = id;
			X = x;
			Z = z;
		}
	}
	public readonly struct StripPosition
	{
		public float Offset { get; }

		public bool Parked { get; }

		public StripPosition(float offset, bool parked)
		{
			Offset = offset;
			Parked = parked;
		}
	}
	public readonly struct StripTick
	{
		public int Degrees { get; }

		public string Label { get; }

		public float Offset { get; }

		public bool North => Degrees == 0;

		public bool Major => Degrees % 45 == 0;

		public StripTick(int degrees, string label, float offset)
		{
			Degrees = degrees;
			Label = label;
			Offset = offset;
		}
	}
	public enum StripMarkKind
	{
		Minor,
		Number,
		Point
	}
	public readonly struct StripMark
	{
		public int Degrees { get; }

		public StripMarkKind Kind { get; }

		public float Offset { get; }

		public StripMark(int degrees, StripMarkKind kind, float offset)
		{
			Degrees = degrees;
			Kind = kind;
			Offset = offset;
		}
	}
	public static class Compass
	{
		public const int MarkStep = 5;

		private static readonly string[] Points = new string[8] { "N", "NE", "E", "SE", "S", "SW", "W", "NW" };

		public const int TickStep = 15;

		public const float MinFade = 0.25f;

		public const float ParkedAlpha = 0.55f;

		public static float EdgeFade(float offset, int width)
		{
			float num = (float)Math.Max(1, width) / 2f;
			float num2 = Math.Min(1f, Math.Abs(offset) / num);
			if (num2 <= 0.7f)
			{
				return 1f;
			}
			return 1f - (num2 - 0.7f) / 0.3f * 0.75f;
		}

		public static float MarkerAlpha(bool parked, float offset, int width)
		{
			if (!parked)
			{
				return EdgeFade(offset, width);
			}
			return 0.55f;
		}

		public static float Heading(float x, float z)
		{
			if (x == 0f && z == 0f)
			{
				return 0f;
			}
			return Wrap360((float)(Math.Atan2(x, z) * 180.0 / Math.PI));
		}

		public static float Bearing(float fromX, float fromZ, float toX, float toZ)
		{
			return Heading(toX - fromX, toZ - fromZ);
		}

		public static float Distance(float fromX, float fromZ, float toX, float toZ)
		{
			float num = toX - fromX;
			float num2 = toZ - fromZ;
			return (float)Math.Sqrt(num * num + num2 * num2);
		}

		public static int Degrees(float heading)
		{
			return (int)Math.Round(Wrap360(heading), MidpointRounding.AwayFromZero) % 360;
		}

		public static string Point(float heading)
		{
			return Points[(int)Math.Round(Wrap360(heading) / 45f, MidpointRounding.AwayFromZero) % 8];
		}

		public static string DistanceText(float metres)
		{
			if (!(metres >= 0f) || float.IsInfinity(metres))
			{
				return "";
			}
			if (!(metres < 1000f))
			{
				return (metres / 1000f).ToString("0.0", CultureInfo.InvariantCulture) + " km";
			}
			return Math.Round(metres, MidpointRounding.AwayFromZero).ToString("0", CultureInfo.InvariantCulture) + " m";
		}

		public static StripPosition OnStrip(float bearing, float heading, int stripDegrees, int width)
		{
			int num = Math.Max(1, stripDegrees);
			float num2 = (float)num / 2f;
			float num3 = Delta(bearing, heading);
			bool parked = Math.Abs(num3) > num2;
			return new StripPosition(Math.Max(0f - num2, Math.Min(num2, num3)) / (float)num * (float)width, parked);
		}

		public static IEnumerable<StripTick> Ticks(float heading, int stripDegrees, int width = 0)
		{
			int span = Math.Max(1, stripDegrees);
			float half = (float)span / 2f;
			int num = (int)Math.Ceiling((heading - half) / 15f) * 15;
			for (int d = num; (float)d <= heading + half + 0.0001f; d += 15)
			{
				int num2 = (d % 360 + 360) % 360;
				string label = ((num2 % 45 == 0) ? Points[num2 / 45] : num2.ToString(CultureInfo.InvariantCulture));
				yield return new StripTick(num2, label, ((float)d - heading) / (float)span * (float)width);
			}
		}

		public static IEnumerable<StripMark> Marks(float heading, int stripDegrees, int width)
		{
			int span = Math.Max(1, stripDegrees);
			float half = (float)span / 2f;
			int num = (int)Math.Ceiling((heading - half) / 5f) * 5;
			for (int d = num; (float)d <= heading + half + 0.0001f; d += 5)
			{
				int num2 = (d % 360 + 360) % 360;
				StripMarkKind kind = ((num2 % 45 == 0) ? StripMarkKind.Point : ((num2 % 15 == 0) ? StripMarkKind.Number : StripMarkKind.Minor));
				yield return new StripMark(num2, kind, ((float)d - heading) / (float)span * (float)width);
			}
		}

		public static IReadOnlyList<MarkerPin> Nearest(IEnumerable<MarkerPin> pins, float x, float z, int max, float maxDistance)
		{
			return (from p in (from p in pins ?? Enumerable.Empty<MarkerPin>()
					select (Pin: p, Distance: Distance(x, z, p.X, p.Z)) into p
					where maxDistance <= 0f || p.Distance <= maxDistance
					orderby p.Distance
					select p).ThenBy<(MarkerPin, float), string>(((MarkerPin Pin, float Distance) p) => p.Pin.Id, StringComparer.Ordinal).Take(Math.Max(0, max))
				select p.Pin).ToList();
		}

		private static float Delta(float bearing, float heading)
		{
			float num = Wrap360(bearing - heading);
			if (!(num >= 180f))
			{
				return num;
			}
			return num - 360f;
		}

		private static float Wrap360(float degrees)
		{
			if (float.IsNaN(degrees) || float.IsInfinity(degrees))
			{
				return 0f;
			}
			float num = degrees % 360f;
			if (!(num < 0f))
			{
				return num;
			}
			return num + 360f;
		}
	}
	public enum HudIcon
	{
		Sun,
		Moon,
		Cloud,
		Rain,
		Storm,
		Snow,
		Mist,
		Ash,
		Boss,
		Indoors
	}
	public static class HudIcons
	{
		private const int Samples = 4;

		private static readonly double[] Arrow = new double[8] { 0.5, 0.06, 0.88, 0.9, 0.5, 0.7, 0.12, 0.9 };

		private static readonly double[] Bolt = new double[14]
		{
			0.56, 0.58, 0.4, 0.8, 0.5, 0.8, 0.44, 0.98, 0.66, 0.72,
			0.54, 0.72, 0.62, 0.58
		};

		private static readonly double[] Roof = new double[6] { 0.5, 0.1, 0.94, 0.5, 0.06, 0.5 };

		public static HudIcon Clock(bool night)
		{
			if (!night)
			{
				return HudIcon.Sun;
			}
			return HudIcon.Moon;
		}

		public static HudIcon For(WeatherCategory category, bool night)
		{
			HudIcon hudIcon = For(category);
			if (hudIcon != HudIcon.Sun)
			{
				return hudIcon;
			}
			return Clock(night);
		}

		public static HudIcon For(WeatherCategory category)
		{
			switch (category)
			{
			case WeatherCategory.Clear:
				return HudIcon.Sun;
			case WeatherCategory.Mist:
				return HudIcon.Mist;
			case WeatherCategory.Rain:
				return HudIcon.Rain;
			case WeatherCategory.Thunderstorm:
				return HudIcon.Storm;
			case WeatherCategory.Snow:
			case WeatherCategory.Blizzard:
				return HudIcon.Snow;
			case WeatherCategory.AshRain:
				return HudIcon.Ash;
			case WeatherCategory.Boss:
				return HudIcon.Boss;
			case WeatherCategory.Indoors:
				return HudIcon.Indoors;
			default:
				return HudIcon.Cloud;
			}
		}

		public static byte[] Mask(HudIcon icon, int size)
		{
			return Sampled(size, (double x, double y) => Inside(icon, x, y));
		}

		public static byte[] PlayerArrow(int size)
		{
			return Sampled(size, (double x, double y) => Polygon(x, y, Arrow));
		}

		private static byte[] Sampled(int size, Func<double, double, bool> inside)
		{
			if (size <= 0)
			{
				return Array.Empty<byte>();
			}
			byte[] array = new byte[size * size];
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					int num = 0;
					for (int k = 0; k < 4; k++)
					{
						for (int l = 0; l < 4; l++)
						{
							double arg = ((double)j + ((double)l + 0.5) / 4.0) / (double)size;
							double arg2 = ((double)i + ((double)k + 0.5) / 4.0) / (double)size;
							if (inside(arg, arg2))
							{
								num++;
							}
						}
					}
					array[i * size + j] = (byte)(num * 255 / 16);
				}
			}
			return array;
		}

		private static bool Inside(HudIcon icon, double x, double y)
		{
			switch (icon)
			{
			case HudIcon.Sun:
				if (!Disc(x, y, 0.5, 0.5, 0.2))
				{
					return Rays(x, y, 0.5, 0.5, 0.31, 0.47, 0.055, 8);
				}
				return true;
			case HudIcon.Moon:
				if (Disc(x, y, 0.5, 0.5, 0.38))
				{
					return !Disc(x, y, 0.64, 0.4, 0.31);
				}
				return false;
			case HudIcon.Cloud:
				return Cloud(x, y, 0.5, 0.5, 1.0);
			case HudIcon.Rain:
				if (!Cloud(x, y, 0.5, 0.36, 0.8) && !Bar(x, y, 0.3, 0.66, 0.3, 0.86, 0.05) && !Bar(x, y, 0.5, 0.7, 0.5, 0.9, 0.05))
				{
					return Bar(x, y, 0.7, 0.66, 0.7, 0.86, 0.05);
				}
				return true;
			case HudIcon.Storm:
				if (!Cloud(x, y, 0.5, 0.34, 0.8))
				{
					return Polygon(x, y, Bolt);
				}
				return true;
			case HudIcon.Snow:
				if (!Rays(x, y, 0.5, 0.5, 0.0, 0.44, 0.05, 6))
				{
					return Disc(x, y, 0.5, 0.5, 0.08);
				}
				return true;
			case HudIcon.Mist:
				if (!Bar(x, y, 0.14, 0.28, 0.86, 0.28, 0.055) && !Bar(x, y, 0.14, 0.5, 0.86, 0.5, 0.055))
				{
					return Bar(x, y, 0.14, 0.72, 0.86, 0.72, 0.055);
				}
				return true;
			case HudIcon.Ash:
				if (!Cloud(x, y, 0.5, 0.36, 0.8) && !Disc(x, y, 0.3, 0.8, 0.065) && !Disc(x, y, 0.5, 0.9, 0.065))
				{
					return Disc(x, y, 0.7, 0.8, 0.065);
				}
				return true;
			case HudIcon.Boss:
				if (!Bar(x, y, 0.5, 0.1, 0.5, 0.6, 0.065))
				{
					return Disc(x, y, 0.5, 0.82, 0.09);
				}
				return true;
			case HudIcon.Indoors:
				if (Polygon(x, y, Roof) || (x >= 0.2 && x <= 0.8 && y >= 0.48 && y <= 0.9))
				{
					if (x >= 0.43 && x <= 0.57 && y >= 0.62)
					{
						return !(y <= 0.9);
					}
					return true;
				}
				return false;
			default:
				return false;
			}
		}

		private static bool Disc(double x, double y, double cx, double cy, double r)
		{
			return (x - cx) * (x - cx) + (y - cy) * (y - cy) <= r * r;
		}

		private static bool Bar(double x, double y, double ax, double ay, double bx, double by, double halfWidth)
		{
			double num = bx - ax;
			double num2 = by - ay;
			double num3 = num * num + num2 * num2;
			double num4 = ((num3 <= 0.0) ? 0.0 : Math.Max(0.0, Math.Min(1.0, ((x - ax) * num + (y - ay) * num2) / num3)));
			double num5 = ax + num4 * num;
			double num6 = ay + num4 * num2;
			return (x - num5) * (x - num5) + (y - num6) * (y - num6) <= halfWidth * halfWidth;
		}

		private static bool Rays(double x, double y, double cx, double cy, double inner, double outer, double halfWidth, int count)
		{
			double num = x - cx;
			double num2 = y - cy;
			double num3 = Math.Sqrt(num * num + num2 * num2);
			if (num3 < inner || num3 > outer)
			{
				return false;
			}
			double num4 = Math.PI * 2.0 / (double)count;
			double num5 = Math.Atan2(num, 0.0 - num2);
			double num6 = Math.Round(num5 / num4) * num4;
			return num3 * Math.Abs(Math.Sin(num5 - num6)) <= halfWidth;
		}

		private static bool Cloud(double x, double y, double cx, double cy, double s)
		{
			double num = 0.5 + (x - cx) / s;
			double num2 = 0.5 + (y - cy) / s;
			if (!Disc(num, num2, 0.3, 0.6, 0.17) && !Disc(num, num2, 0.7, 0.6, 0.17) && !Disc(num, num2, 0.5, 0.46, 0.22))
			{
				if (num >= 0.3 && num <= 0.7 && num2 >= 0.5)
				{
					return num2 <= 0.77;
				}
				return false;
			}
			return true;
		}

		private static bool Polygon(double x, double y, double[] points)
		{
			bool flag = false;
			int num = points.Length / 2;
			int num2 = 0;
			int num3 = num - 1;
			while (num2 < num)
			{
				double num4 = points[2 * num2];
				double num5 = points[2 * num2 + 1];
				double num6 = points[2 * num3];
				double num7 = points[2 * num3 + 1];
				if (num5 > y != num7 > y && x < (num6 - num4) * (y - num5) / (num7 - num5) + num4)
				{
					flag = !flag;
				}
				num3 = num2++;
			}
			return flag;
		}
	}
	public enum HudRow
	{
		Status,
		Compass,
		Heading,
		Sleep,
		Tempest,
		Radius,
		RadiusInputs
	}
	public readonly struct HudOptions
	{
		public bool ShowDay { get; }

		public bool ShowTime { get; }

		public bool ShowWeather { get; }

		public bool ShowCompass { get; }

		public bool ShowHeading { get; }

		public bool ShowRadius { get; }

		public bool ShowRadiusInputs { get; }

		public bool Sleep { get; }

		public bool Forecast { get; }

		public TempestLineKind Tempest { get; }

		public HudOptions(bool showDay, bool showTime, bool showWeather, bool showCompass, bool showHeading, bool showRadius, bool showRadiusInputs, TempestLineKind tempest, bool sleep = false, bool forecast = false)
		{
			ShowDay = showDay;
			ShowTime = showTime;
			ShowWeather = showWeather;
			ShowCompass = showCompass;
			ShowHeading = showHeading;
			ShowRadius = showRadius;
			ShowRadiusInputs = showRadiusInputs;
			Tempest = tempest;
			Sleep = sleep;
			Forecast = forecast;
		}
	}
	public readonly struct HudSize
	{
		public int Width { get; }

		public int Height { get; }

		public HudSize(int width, int height)
		{
			Width = width;
			Height = height;
		}
	}
	public static class HudLayout
	{
		public const int StripCap = 22;

		public const float Scale = 1.3333334f;

		public const int TopGap = 14;

		public const int MinWidth = 240;

		public const int MaxWidth = 640;

		public const int StatusHeight = 17;

		public const int CompassRowHeight = 22;

		public const int IconSize = 15;

		public const int PointerTop = 1;

		public const int PointerHeight = 6;

		public const int TickLabelTop = 8;

		public const int TickLabelHeight = 14;

		public const int HeadingHeight = 12;

		public const int HeadingInsetWidth = 64;

		public const int HeadingInsetHeight = 14;

		public const int ExtraRowHeight = 14;

		public const int PlankPad = 5;

		public const float StatusFontSize = 12f;

		public const float StatusMinFontSize = 8f;

		public const float StatusGap = 7f;

		public const float IconGap = 3f;

		public const float StatusEffectMargin = 8f;

		public static IReadOnlyList<HudRow> Rows(HudOptions options)
		{
			List<HudRow> list = new List<HudRow>();
			if (options.ShowDay || options.ShowTime || options.ShowWeather || options.Forecast)
			{
				list.Add(HudRow.Status);
			}
			if (options.ShowCompass)
			{
				list.Add(HudRow.Compass);
			}
			if (options.ShowCompass && options.ShowHeading)
			{
				list.Add(HudRow.Heading);
			}
			if (options.Sleep)
			{
				list.Add(HudRow.Sleep);
			}
			if (options.Tempest != TempestLineKind.None)
			{
				list.Add(HudRow.Tempest);
			}
			if (options.ShowRadius)
			{
				list.Add(HudRow.Radius);
			}
			if (options.ShowRadiusInputs)
			{
				list.Add(HudRow.RadiusInputs);
			}
			return list;
		}

		public static int PlankHeight(IReadOnlyList<HudRow> rows)
		{
			int num = 0;
			bool flag = false;
			foreach (HudRow item in rows ?? Array.Empty<HudRow>())
			{
				if (!IsExtra(item))
				{
					num += RowHeight(item);
					flag = flag || item == HudRow.Heading;
				}
			}
			if (num != 0)
			{
				return num + 5 + ((!flag) ? 5 : 0);
			}
			return 0;
		}

		public static bool IsExtra(HudRow row)
		{
			if (row != HudRow.Status && row != HudRow.Compass)
			{
				return row != HudRow.Heading;
			}
			return false;
		}

		public static int RowHeight(HudRow row)
		{
			return row switch
			{
				HudRow.Status => 17, 
				HudRow.Compass => 22, 
				HudRow.Heading => 12, 
				_ => 14, 
			};
		}

		public static int Top(IReadOnlyList<HudRow> rows, HudRow row)
		{
			if (rows == null)
			{
				rows = Array.Empty<HudRow>();
			}
			int num = (IsExtra(row) ? PlankHeight(rows) : 5);
			foreach (HudRow row2 in rows)
			{
				if (row2 == row)
				{
					return num;
				}
				if (IsExtra(row2) == IsExtra(row))
				{
					num += RowHeight(row2);
				}
			}
			return num;
		}

		public static HudSize Size(IReadOnlyList<HudRow> rows, int compassWidth = 240)
		{
			if (rows == null)
			{
				rows = Array.Empty<HudRow>();
			}
			int num = PlankHeight(rows);
			bool flag = false;
			foreach (HudRow row in rows)
			{
				if (IsExtra(row))
				{
					num += RowHeight(row);
				}
				flag = flag || row == HudRow.Compass;
			}
			return new HudSize(flag ? Math.Min(640, Math.Max(240, compassWidth)) : 240, num);
		}

		public static (float Clock, float Divider, float Weather) StatusPlaces(float panelWidth, float clockGroup, float weatherGroup, float gap)
		{
			float num = panelWidth * 0.5f;
			if (clockGroup <= 0f)
			{
				return (Clock: num, Divider: num, Weather: num - weatherGroup * 0.5f);
			}
			if (weatherGroup <= 0f)
			{
				return (Clock: num - clockGroup * 0.5f, Divider: num, Weather: num);
			}
			float num2 = num - (clockGroup + 2f * gap + weatherGroup) * 0.5f;
			return (Clock: num2, Divider: num2 + clockGroup + gap, Weather: num2 + clockGroup + 2f * gap);
		}

		public static float StatusRoom(float panelWidth)
		{
			return panelWidth - 36f;
		}

		public static float WeatherTextRoom(float panelWidth, float clockGroup)
		{
			return Math.Max(0f, StatusRoom(panelWidth) - ((clockGroup > 0f) ? (clockGroup + 14f) : 0f) - 15f - 3f);
		}

		public static (float Size, bool Ellipsis) FitText(float widthAtBase, float room, float baseSize = 12f, float minSize = 8f)
		{
			if (widthAtBase <= room)
			{
				return (Size: baseSize, Ellipsis: false);
			}
			float num = ((room <= 0f) ? 0f : ((float)Math.Floor(baseSize * room / widthAtBase * 2f) / 2f));
			if (!(num >= minSize))
			{
				return (Size: minSize, Ellipsis: true);
			}
			return (Size: num, Ellipsis: false);
		}

		public static (int X, int Y) Home(int parentWidth, int shownWidth)
		{
			return (X: (parentWidth - shownWidth) / 2, Y: 14);
		}

		public static bool Visible(bool enabled, bool allowsUi, bool steppedAside, bool toggledOff, bool blocked)
		{
			if (enabled && allowsUi && !steppedAside && !toggledOff)
			{
				return !blocked;
			}
			return false;
		}

		public static bool OwnsSleep(bool enabled, bool allowsUi, bool steppedAside, bool toggledOff, bool reading)
		{
			return enabled && allowsUi && !steppedAside && !toggledOff && reading;
		}

		public static int StatusEffectsPerRow(int nativePerRow, float firstCenter, float cell, bool plankShown, float plankRight, float plankTop, float plankBottom, float rowTop, float rowBottom)
		{
			int num = Math.Max(1, nativePerRow);
			if (!plankShown || cell <= 0f || plankBottom <= rowTop || plankTop >= rowBottom)
			{
				return num;
			}
			float num2 = firstCenter - cell * 0.5f - (plankRight + 8f);
			if (num2 < 0f)
			{
				return 1;
			}
			return Math.Max(1, Math.Min(num, 1 + (int)Math.Floor(num2 / cell)));
		}
	}
	public sealed class StatusRowHold
	{
		public const int ReleaseFrames = 2;

		private bool holding;

		private int lastOpenFrame;

		public bool Holding(bool windowOpen, int frame)
		{
			if (windowOpen)
			{
				holding = true;
				lastOpenFrame = frame;
				return true;
			}
			if (holding && frame >= lastOpenFrame && frame - lastOpenFrame <= 2)
			{
				return true;
			}
			holding = false;
			return false;
		}

		public void Reset()
		{
			holding = false;
		}
	}
	public readonly struct ClockParts
	{
		public string Day { get; }

		public string Time { get; }

		public ClockParts(string day, string time)
		{
			Day = day;
			Time = time;
		}
	}
	public readonly struct HeadingParts
	{
		public string Degrees { get; }

		public string PointKey { get; }

		public HeadingParts(string degrees, string pointKey)
		{
			Degrees = degrees;
			PointKey = pointKey;
		}
	}
	public static class HudText
	{
		public static ClockParts Clock(bool showDay, bool showTime, int day, float dayFraction, bool use24Hour)
		{
			return new ClockParts(showDay ? Math.Max(0, day).ToString(CultureInfo.InvariantCulture) : "", showTime ? ExtraPotions.Cairn.Hud.Clock.Text(dayFraction, use24Hour) : "");
		}

		public static string Join(string first, string second)
		{
			if (string.IsNullOrEmpty(first))
			{
				return second ?? "";
			}
			if (string.IsNullOrEmpty(second))
			{
				return first;
			}
			return first + "  " + second;
		}

		public static string Dot(string first, string second)
		{
			if (string.IsNullOrEmpty(first))
			{
				return second ?? "";
			}
			if (string.IsNullOrEmpty(second))
			{
				return first;
			}
			return first + " · " + second;
		}

		public static string WithForecast(string? current, string? next, bool combinedFits)
		{
			if (current == null)
			{
				current = "";
			}
			if (next == null)
			{
				next = "";
			}
			if (next.Length == 0)
			{
				return current;
			}
			if (current.Length == 0 || !combinedFits)
			{
				return next;
			}
			return Dot(current, next);
		}

		public static HeadingParts Heading(float heading)
		{
			return new HeadingParts(Compass.Degrees(heading).ToString(CultureInfo.InvariantCulture), CairnTextKeys.CompassPoint(Compass.Point(heading)));
		}

		public static string RadiusArgument(RadiusResult result)
		{
			return Whole(result.Radius);
		}

		public static string[] RadiusInputArguments(RadiusResult result)
		{
			return new string[7]
			{
				Whole(result.Radius),
				Whole(result.Base),
				result.Multiplier.ToString("0.00", CultureInfo.InvariantCulture),
				Signed(result.LightTerm),
				Signed(result.WeatherTerm),
				Signed(result.AltitudeTerm),
				Signed(result.LocationTerm)
			};
		}

		private static string Whole(float value)
		{
			return Math.Round(value, MidpointRounding.AwayFromZero).ToString("0", CultureInfo.InvariantCulture);
		}

		private static string Signed(float value)
		{
			return value.ToString("+0.00;-0.00;0.00", CultureInfo.InvariantCulture);
		}
	}
	public readonly struct SleepRowCells
	{
		public const float Moon = 18f;

		public const float Bed = 20f;

		public const float Gap = 3f;

		public const float CountMinWidth = 26f;

		public const float BoostGap = 8f;

		public const float BoostWidth = 36f;

		public const float Rivet = 9f;

		public const float RivetInset = 3f;

		public const float Edge = 14f;

		public const float GroupWidth = 114f;

		public float MoonX { get; }

		public float BedX { get; }

		public float CountX { get; }

		public float CountWidth { get; }

		public float BoostX { get; }

		public SleepRowCells(float width, float height)
		{
			MoonX = Math.Max(14f, (width - 114f) / 2f);
			BedX = MoonX + 18f + 3f;
			CountX = BedX + 20f + 3f;
			CountWidth = 26f;
			BoostX = CountX + CountWidth + 8f;
		}
	}
	public static class WeatherDisplayCapability
	{
		public const string Id = "meadworks.cairn.weather_display";

		public static Version ContractVersion { get; } = new Version(1, 0);

		public static bool Showing(bool panelVisible, bool tempestRowEnabled, TempestLineKind kind)
		{
			if (panelVisible && tempestRowEnabled)
			{
				return kind != TempestLineKind.None;
			}
			return false;
		}
	}
	public sealed class MarkerChoices
	{
		public const string Header = "cairn-markers 1";

		private readonly SortedSet<string> entries;

		public static MarkerChoices Default => new MarkerChoices(new string[1] { "type:Death" });

		public static MarkerChoices Empty => new MarkerChoices(Array.Empty<string>());

		public IReadOnlyList<string> Entries => entries.ToList();

		private MarkerChoices(IEnumerable<string> entries)
		{
			this.entries = new SortedSet<string>(entries, StringComparer.Ordinal);
		}

		public bool Contains(string entry)
		{
			return entries.Contains(entry);
		}

		public MarkerChoices With(string entry)
		{
			if (!IsEntry(entry))
			{
				throw new ArgumentException("Not a marker entry: " + entry, "entry");
			}
			return new MarkerChoices(entries.Concat(new string[1] { entry }));
		}

		public MarkerChoices Without(string entry)
		{
			return new MarkerChoices(entries.Where((string e) => e != entry));
		}

		public static string DataKey(long worldId)
		{
			return "Cairn.compassMarkers." + worldId.ToString(CultureInfo.InvariantCulture);
		}

		public static string PinKey(float x, float z, string pinType)
		{
			return "pin:" + Math.Round(x, MidpointRounding.AwayFromZero).ToString("0", CultureInfo.InvariantCulture) + "," + Math.Round(z, MidpointRounding.AwayFromZero).ToString("0", CultureInfo.InvariantCulture) + "," + pinType;
		}

		public static bool IsEntry(string? entry)
		{
			if (string.IsNullOrEmpty(entry))
			{
				return false;
			}
			if (entry.StartsWith("type:", StringComparison.Ordinal))
			{
				return IsName(entry.Substring(5));
			}
			if (!entry.StartsWith("pin:", StringComparison.Ordinal))
			{
				return false;
			}
			string[] array = entry.Substring(4).Split(',');
			if (array.Length == 3 && int.TryParse(array[0], NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out var result) && int.TryParse(array[1], NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out result))
			{
				return IsName(array[2]);
			}
			return false;
		}

		public string Serialize()
		{
			return string.Join("\n", new string[1] { "cairn-markers 1" }.Concat(entries));
		}

		public static MarkerChoices Parse(string? text)
		{
			if (string.IsNullOrWhiteSpace(text))
			{
				return Default;
			}
			List<string> list = (from l in text.Replace("\r", "").Split('\n')
				select l.Trim() into l
				where l.Length > 0
				select l).ToList();
			if (list.Count == 0 || list[0] != "cairn-markers 1")
			{
				return Default;
			}
			return new MarkerChoices(list.Skip(1).Where(IsEntry));
		}

		private static bool IsName(string name)
		{
			if (name.Length > 0)
			{
				return name.All((char c) => char.IsLetterOrDigit(c) || c == '_');
			}
			return false;
		}
	}
	public sealed class MapPinInfo
	{
		public string Type { get; }

		public float X { get; }

		public float Z { get; }

		public string Name { get; }

		public MapPinInfo(string type, float x, float z, string name)
		{
			Type = (type ?? "").Trim();
			X = x;
			Z = z;
			Name = name ?? "";
		}
	}
	public enum MarkerShown
	{
		Hidden,
		ByType,
		ByPin
	}
	public sealed class MarkerMapPin
	{
		public MapPinInfo Pin { get; }

		public string Entry { get; }

		public MarkerShown Shown { get; }

		internal MarkerMapPin(MapPinInfo pin, string entry, MarkerShown shown)
		{
			Pin = pin;
			Entry = entry;
			Shown = shown;
		}
	}
	public sealed class MarkerTypeGroup
	{
		public string Type { get; }

		public int Count { get; }

		public bool Chosen { get; }

		public string Entry => TypeEntry(Type);

		internal MarkerTypeGroup(string type, int count, bool chosen)
		{
			Type = type;
			Count = count;
			Chosen = chosen;
		}

		internal static string TypeEntry(string type)
		{
			return "type:" + type;
		}
	}
	public readonly struct MarkerToggle
	{
		public MarkerChoices Choices { get; }

		public bool Changed { get; }

		public bool ShownByType { get; }

		public MarkerToggle(MarkerChoices choices, bool changed, bool shownByType)
		{
			Choices = choices;
			Changed = changed;
			ShownByType = shownByType;
		}
	}
	public sealed class MarkerMapPlan
	{
		public IReadOnlyList<MarkerMapPin> Pins { get; }

		public IReadOnlyList<MarkerTypeGroup> Types { get; }

		private MarkerMapPlan(IReadOnlyList<MarkerMapPin> pins, IReadOnlyList<MarkerTypeGroup> types)
		{
			Pins = pins;
			Types = types;
		}

		public static MarkerMapPlan Build(IEnumerable<MapPinInfo> pins, MarkerChoices choices)
		{
			if (pins == null)
			{
				throw new ArgumentNullException("pins");
			}
			if (choices == null)
			{
				throw new ArgumentNullException("choices");
			}
			List<MapPinInfo> list = pins.Where((MapPinInfo p) => p != null && Finite(p.X) && Finite(p.Z) && MarkerChoices.IsEntry(MarkerTypeGroup.TypeEntry(p.Type))).OrderBy<MapPinInfo, string>((MapPinInfo p) => p.Type, StringComparer.Ordinal).ThenBy<MapPinInfo, string>((MapPinInfo p) => p.Name, StringComparer.OrdinalIgnoreCase)
				.ThenBy((MapPinInfo p) => p.X)
				.ThenBy((MapPinInfo p) => p.Z)
				.ToList();
			List<MarkerMapPin> list2 = new List<MarkerMapPin>(list.Count);
			foreach (MapPinInfo item in list)
			{
				string entry = MarkerChoices.PinKey(item.X, item.Z, item.Type);
				MarkerShown shown = (choices.Contains(MarkerTypeGroup.TypeEntry(item.Type)) ? MarkerShown.ByType : (choices.Contains(entry) ? MarkerShown.ByPin : MarkerShown.Hidden));
				list2.Add(new MarkerMapPin(item, entry, shown));
			}
			List<MarkerTypeGroup> list3 = (from g in list.GroupBy<MapPinInfo, string>((MapPinInfo p) => p.Type, StringComparer.Ordinal)
				select new MarkerTypeGroup(g.Key, g.Count(), choices.Contains(MarkerTypeGroup.TypeEntry(g.Key)))).ToList();
			return new MarkerMapPlan(list2.AsReadOnly(), list3.AsReadOnly());
		}

		public MarkerToggle Toggle(int index, MarkerChoices choices)
		{
			if (choices == null)
			{
				throw new ArgumentNullException("choices");
			}
			if (index < 0 || index >= Pins.Count)
			{
				return new MarkerToggle(choices, changed: false, shownByType: false);
			}
			MarkerMapPin markerMapPin = Pins[index];
			if (choices.Contains(MarkerTypeGroup.TypeEntry(markerMapPin.Pin.Type)))
			{
				return new MarkerToggle(choices, changed: false, shownByType: true);
			}
			return new MarkerToggle(choices.Contains(markerMapPin.Entry) ? choices.Without(markerMapPin.Entry) : choices.With(markerMapPin.Entry), changed: true, shownByType: false);
		}

		public MarkerChoices ToggleType(string type, MarkerChoices choices)
		{
			if (choices == null)
			{
				throw new ArgumentNullException("choices");
			}
			string entry = MarkerTypeGroup.TypeEntry((type ?? "").Trim());
			if (!MarkerChoices.IsEntry(entry))
			{
				return choices;
			}
			if (!choices.Contains(entry))
			{
				return choices.With(entry);
			}
			return choices.Without(entry);
		}

		private static bool Finite(float v)
		{
			if (!float.IsNaN(v))
			{
				return !float.IsInfinity(v);
			}
			return false;
		}
	}
	public static class MarkerMapImage
	{
		public const uint Fog = 11574129u;

		public const uint Water = 4481132u;

		public const float StartZoom = 8f;

		public const float LargePinSize = 48f;

		public const float ArrowSize = 22f;

		public const float DimmedAlpha = 0.7f;

		public static float PinSize(float largeMapPinSize)
		{
			if (!float.IsNaN(largeMapPinSize) && !float.IsInfinity(largeMapPinSize) && !(largeMapPinSize <= 0f))
			{
				return largeMapPinSize;
			}
			return 48f;
		}

		public static float PlayerRotation(float heading)
		{
			if (float.IsNaN(heading) || float.IsInfinity(heading))
			{
				return 0f;
			}
			float num = 0f - heading % 360f;
			if (num <= -180f)
			{
				num += 360f;
			}
			if (num > 180f)
			{
				num -= 360f;
			}
			if (num != 0f)
			{
				return num;
			}
			return 0f;
		}

		public static (float X, float Y, float Zoom) StartView(float playerX, float playerY)
		{
			if (float.IsNaN(playerX) || float.IsInfinity(playerX) || float.IsNaN(playerY) || float.IsInfinity(playerY) || !(playerX >= 0f) || !(playerX <= 1f) || !(playerY >= 0f) || !(playerY <= 1f))
			{
				return (X: 0.5f, Y: 0.5f, Zoom: 1f);
			}
			return (X: playerX, Y: playerY, Zoom: 8f);
		}

		public static IReadOnlyDictionary<uint, uint> Palette(uint meadows, uint blackForest, uint swamp, uint mountain, uint plains, uint mistlands, uint ashLands, uint deepNorth)
		{
			Dictionary<uint, uint> map = new Dictionary<uint, uint>();
			Add(meadows, 8031302u);
			Add(blackForest, 4346426u);
			Add(swamp, 6444094u);
			Add(mountain, 13816525u);
			Add(plains, 12232796u);
			Add(mistlands, 6053992u);
			Add(ashLands, 7879212u);
			Add(deepNorth, 14476008u);
			return map;
			void Add(uint tint, uint painted)
			{
				if (!map.ContainsKey(tint & 0xFFFFFF))
				{
					map.Add(tint & 0xFFFFFF, painted);
				}
			}
		}

		public static void Compose(byte[] rgba, int count, Func<int, uint> biome, Func<int, bool> explored, Func<int, float> height, float waterLevel, IReadOnlyDictionary<uint, uint> palette)
		{
			if (rgba == null || biome == null || explored == null || height == null || palette == null)
			{
				throw new ArgumentNullException("rgba");
			}
			if (count < 0 || rgba.Length < count * 4)
			{
				throw new ArgumentException("The pixel buffer is shorter than the map.", "rgba");
			}
			for (int i = 0; i < count; i++)
			{
				uint num;
				if (!explored(i))
				{
					num = 11574129u;
				}
				else if (height(i) < waterLevel)
				{
					num = 4481132u;
				}
				else
				{
					uint num2 = biome(i) & 0xFFFFFF;
					num = (palette.TryGetValue(num2, out var value) ? value : num2);
				}
				int num3 = i * 4;
				rgba[num3] = (byte)(num >> 16);
				rgba[num3 + 1] = (byte)(num >> 8);
				rgba[num3 + 2] = (byte)num;
				rgba[num3 + 3] = byte.MaxValue;
			}
		}
	}
	public readonly struct SleepDisplay
	{
		public const string CapabilityId = "meadworks.cairn.sleep_display";

		public static Version ContractVersion { get; } = new Version(1, 0);

		public bool Visible { get; }

		public string Sleeping { get; }

		public string Players { get; }

		public string BoostPercent { get; }

		public string SkipPercent { get; }

		public SleepDisplay(bool windowOpen, int players, int sleeping, double extraRate, bool skipRunning, float skipProgress)
		{
			Visible = players > 0 && (skipRunning || (windowOpen && sleeping > 0));
			Players = Math.Max(0, players).ToString(CultureInfo.InvariantCulture);
			Sleeping = Math.Max(0, Math.Min(players, sleeping)).ToString(CultureInfo.InvariantCulture);
			double num = ((extraRate > 0.0 && players > 1) ? Math.Min(1.0, (double)sleeping / (double)(players - 1)) : 0.0);
			BoostPercent = Math.Max(0.0, 100.0 * num).ToString("F0", CultureInfo.InvariantCulture);
			SkipPercent = (skipRunning ? (100f * Math.Max(0f, Math.Min(1f, skipProgress))).ToString("F0", CultureInfo.InvariantCulture) : "");
		}
	}
	public static class SleepRowLayout
	{
		public const float Height = 40f;

		public const float Gap = 1f;

		public static readonly byte[] BoostColour = new byte[3] { 255, 183, 91 };
	}
	public enum TempestKind
	{
		None,
		Blizzard,
		Thunderstorm,
		LightningStorm,
		DenseFog,
		AshStorm,
		MeteorShower
	}
	public enum TempestGlyph
	{
		None,
		Snowflake,
		Bolt,
		Cloud,
		Star
	}
	public enum TempestPhase
	{
		Idle,
		Warning,
		Active,
		Clearing
	}
	public enum TempestLineKind
	{
		None,
		Warning,
		Active,
		Clearing
	}
	public readonly struct TempestLine
	{
		public static TempestLine None => new TempestLine(TempestLineKind.None, "", "", "");

		public TempestLineKind Kind { get; }

		public string TextKey { get; }

		public string EventKey { get; }

		public string Countdown { get; }

		public TempestGlyph Glyph { get; }

		public TempestLine(TempestLineKind kind, string textKey, string eventKey, string countdown, TempestGlyph glyph = TempestGlyph.None)
		{
			Kind = kind;
			TextKey = textKey;
			EventKey = eventKey;
			Countdown = countdown;
			Glyph = glyph;
		}
	}
	public static class TempestWarning
	{
		public static readonly string[] Tokens = new string[6] { "blizzard", "thunderstorm", "lightning_storm", "dense_fog", "ash_storm", "meteor_shower" };

		public static bool Reaches(int biomes, int localBiome, bool localAffected)
		{
			if (!localAffected)
			{
				return (biomes & localBiome) != 0;
			}
			return true;
		}

		public static TempestLine Line(bool enabled, TempestKind kind, TempestPhase phase, float secondsLeft, int biomes, int localBiome, bool localAffected, string? token = null)
		{
			if (!enabled || !Reaches(biomes, localBiome, localAffected))
			{
				return TempestLine.None;
			}
			string text = Token(kind);
			string text2;
			if (token != null && Array.IndexOf<string>(Tokens, token) >= 0)
			{
				text2 = CairnTextKeys.TempestToken(token);
			}
			else
			{
				if (text == null)
				{
					return TempestLine.None;
				}
				text2 = CairnTextKeys.TempestEvent(kind);
			}
			TempestGlyph glyph = GlyphOf((text != null) ? kind : KindOf(token));
			return phase switch
			{
				TempestPhase.Warning => new TempestLine(TempestLineKind.Warning, "tempest_warning", text2, Countdown(secondsLeft), glyph), 
				TempestPhase.Active => new TempestLine(TempestLineKind.Active, text2, text2, "", glyph), 
				TempestPhase.Clearing => new TempestLine(TempestLineKind.Clearing, "tempest_clearing", text2, "", glyph), 
				_ => TempestLine.None, 
			};
		}

		public static string? Token(TempestKind kind)
		{
			if (kind <= TempestKind.None || (int)kind > Tokens.Length)
			{
				return null;
			}
			return Tokens[(int)(kind - 1)];
		}

		private static TempestKind KindOf(string token)
		{
			return (TempestKind)(Array.IndexOf(Tokens, token) + 1);
		}

		public static (string Key, TempestGlyph Glyph)? StatusEvent(WeatherCategory category, string? environment, TempestLine line)
		{
			if (category == WeatherCategory.Indoors || category == WeatherCategory.Boss)
			{
				return null;
			}
			string text = WeatherCategories.EventToken(environment);
			if (text != null)
			{
				return (CairnTextKeys.TempestToken(text), GlyphOf(KindOf(text)));
			}
			if (line.Kind == TempestLineKind.Active)
			{
				return (line.EventKey, line.Glyph);
			}
			return null;
		}

		public static TempestGlyph GlyphOf(TempestKind kind)
		{
			switch (kind)
			{
			case TempestKind.Blizzard:
				return TempestGlyph.Snowflake;
			case TempestKind.Thunderstorm:
			case TempestKind.LightningStorm:
				return TempestGlyph.Bolt;
			case TempestKind.DenseFog:
				return TempestGlyph.Cloud;
			case TempestKind.AshStorm:
			case TempestKind.MeteorShower:
				return TempestGlyph.Star;
			default:
				return TempestGlyph.None;
			}
		}

		public static string Countdown(float seconds)
		{
			if (float.IsNaN(seconds) || float.IsInfinity(seconds) || seconds <= 0f)
			{
				return "0:00";
			}
			int num = (int)Math.Ceiling(Math.Min(seconds, 359999f));
			return (num / 60).ToString(CultureInfo.InvariantCulture) + ":" + (num % 60).ToString("00", CultureInfo.InvariantCulture);
		}
	}
	public readonly struct TempestReading
	{
		public int Kind { get; }

		public TempestPhase Phase { get; }

		public float SecondsLeft { get; }

		public int Biomes { get; }

		public bool LocalAffected { get; }

		public int Revision { get; }

		public string Token { get; }

		public bool Running => Phase != TempestPhase.Idle;

		public TempestReading(int kind, TempestPhase phase, float secondsLeft, int biomes, bool localAffected, int revision, string token)
		{
			Kind = kind;
			Phase = phase;
			SecondsLeft = secondsLeft;
			Biomes = biomes;
			LocalAffected = localAffected;
			Revision = revision;
			Token = token ?? "";
		}
	}
	public static class TempestDetail
	{
		public const string Id = "meadworks.weather.events.detail";

		public static readonly Version ContractVersion = new Version(1, 0);

		public const float MaximumSecondsLeft = 3600f;

		public static bool TryRead(Tuple<int, int, float, int, bool, int, string>? raw, out TempestReading reading)
		{
			reading = default(TempestReading);
			if (raw == null || !Valid(raw.Item1, raw.Item2, raw.Item3, raw.Item4, raw.Item5, raw.Item7))
			{
				return false;
			}
			reading = new TempestReading(raw.Item1, (TempestPhase)raw.Item2, raw.Item3, raw.Item4, raw.Item5, raw.Item6, raw.Item7);
			return true;
		}

		public static bool TryRead(Func<Tuple<int, int, float, int, bool, int, string>>? provider, out TempestReading reading)
		{
			reading = default(TempestReading);
			if (provider == null)
			{
				return false;
			}
			Tuple<int, int, float, int, bool, int, string> raw;
			try
			{
				raw = provider();
			}
			catch
			{
				return false;
			}
			return TryRead(raw, out reading);
		}

		private static bool Valid(int kind, int phase, float seconds, int biomes, bool local, string? token)
		{
			if (kind < 0 || phase < 0 || phase > 3 || biomes < 0)
			{
				return false;
			}
			if (float.IsNaN(seconds) || float.IsInfinity(seconds) || seconds < 0f || seconds > 3600f)
			{
				return false;
			}
			if (phase == 0)
			{
				if (kind == 0 && seconds == 0f && biomes == 0 && !local)
				{
					return string.IsNullOrEmpty(token);
				}
				return false;
			}
			if (kind == 0 || string.IsNullOrEmpty(token) || token.Length > 32)
			{
				return false;
			}
			foreach (char c in token)
			{
				if ((c < 'a' || c > 'z') && (c < '0' || c > '9') && c != '_')
				{
					return false;
				}
			}
			return true;
		}
	}
	public sealed class TempestNotice
	{
		private int? announced;

		public static bool HudRowDrawn { get; set; }

		public static bool CentreEnabled => ShowCentre(HudRowDrawn);

		public static bool ShowCentre(bool hudRowDrawn)
		{
			return hudRowDrawn;
		}

		public bool Update(int revision, TempestPhase phase, bool relevant)
		{
			if (phase != TempestPhase.Warning || !relevant || announced == revision)
			{
				return false;
			}
			announced = revision;
			return true;
		}

		public void Reset()
		{
			announced = null;
		}
	}
	public static class TidyPinRules
	{
		public const float IconScale = 0.75f;

		public const float CheckedAlpha = 0.35f;

		public static bool KeepsGameLook(string pinType)
		{
			if (!(pinType == "Player") && !(pinType == "Ping"))
			{
				return pinType == "Shout";
			}
			return true;
		}

		public static float Scale(string pinType, bool hovered, float hoverScale)
		{
			float num = (KeepsGameLook(pinType) ? 1f : 0.75f);
			if (hovered && !float.IsNaN(hoverScale) && hoverScale > 1f)
			{
				num *= hoverScale;
			}
			return num;
		}

		public static float Alpha(string pinType, bool isChecked)
		{
			if (!isChecked || KeepsGameLook(pinType))
			{
				return 1f;
			}
			return 0.35f;
		}

		public static bool ShowsName(bool largeMap, bool hovered, bool showAll, string name)
		{
			if (largeMap && (hovered || showAll))
			{
				return !string.IsNullOrEmpty(name);
			}
			return false;
		}
	}
	public enum WeatherCategory
	{
		Clear,
		Cloudy,
		Mist,
		Rain,
		Thunderstorm,
		Snow,
		Blizzard,
		AshRain,
		Boss,
		Indoors
	}
	public static class WeatherCategories
	{
		public const float CloudyFogDensity = 0.02f;

		private static readonly Dictionary<string, WeatherCategory> Table = Build();

		private static readonly Dictionary<string, string> EventTokens = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			["Tempest_Blizzard"] = "blizzard",
			["Tempest_Whiteout"] = "blizzard",
			["Tempest_Storm"] = "thunderstorm",
			["Tempest_LightningStorm"] = "lightning_storm",
			["Tempest_Fog"] = "dense_fog",
			["Tempest_AshStorm"] = "ash_storm",
			["Tempest_MeteorShower"] = "meteor_shower"
		};

		private static readonly Dictionary<string, string> Aliases = BuildAliases();

		public static IReadOnlyDictionary<string, WeatherCategory> Known => Table;

		public static IReadOnlyDictionary<string, string> SeasonalAliases => Aliases;

		public static WeatherCategory Of(string? environment, float fogDensity, bool rainy, bool interior = false)
		{
			if (interior)
			{
				return WeatherCategory.Indoors;
			}
			if (!string.IsNullOrWhiteSpace(environment))
			{
				string key = environment.Trim();
				if (Table.TryGetValue(key, out var value))
				{
					return value;
				}
				if (Aliases.TryGetValue(key, out string value2) && Table.TryGetValue(value2, out value))
				{
					return value;
				}
			}
			if (!rainy && !(fogDensity >= 0.02f))
			{
				return WeatherCategory.Clear;
			}
			return WeatherCategory.Cloudy;
		}

		public static string BaseName(string? environment)
		{
			if (string.IsNullOrWhiteSpace(environment))
			{
				return "";
			}
			string text = environment.Trim();
			if (!Aliases.TryGetValue(text, out string value))
			{
				return text;
			}
			return value;
		}

		public static string? EventToken(string? environment)
		{
			if (environment == null || !EventTokens.TryGetValue(environment.Trim(), out string value))
			{
				return null;
			}
			return value;
		}

		private static Dictionary<string, WeatherCategory> Build()
		{
			Dictionary<string, WeatherCategory> t = new Dictionary<string, WeatherCategory>(StringComparer.OrdinalIgnoreCase);
			Add(WeatherCategory.Clear, new string[4] { "Clear", "Twilight_Clear", "Heath clear", "Mistlands_clear" });
			Add(WeatherCategory.Cloudy, new string[10] { "Darklands_dark", "Ghosts", "Morkhalla", "TheHollow", "JotunInvasion_meadows", "JotunInvasion_blackforest", "JotunInvasion_swamp", "JotunInvasion_mountain", "JotunInvasion_plains", "JotunInvasion_mistlands" });
			Add(WeatherCategory.Mist, new string[4] { "Misty", "DeepForest Mist", "Ashlands_misty", "Tempest_Fog" });
			Add(WeatherCategory.Rain, new string[4] { "Rain", "LightRain", "SwampRain", "Mistlands_rain" });
			Add(WeatherCategory.Thunderstorm, new string[7] { "ThunderStorm", "Mistlands_thunder", "nofogts", "Ashlands_storm", "Ashlands_SeaStorm", "Tempest_Storm", "Tempest_LightningStorm" });
			Add(WeatherCategory.Snow, new string[2] { "Snow", "Twilight_Snow" });
			Add(WeatherCategory.Blizzard, new string[4] { "SnowStorm", "Twilight_SnowStorm", "Tempest_Blizzard", "Tempest_Whiteout" });
			Add(WeatherCategory.AshRain, new string[6] { "Ashrain", "Ashlands_ashrain", "Ashlands_CinderRain", "Ashlands_meteorshower", "Tempest_AshStorm", "Tempest_MeteorShower" });
			Add(WeatherCategory.Boss, new string[9] { "Eikthyr", "Eikthyr_no_lightning", "GDKing", "Bonemass", "Moder", "GoblinKing", "Queen", "Fader", "DN_Bossroom" });
			Add(WeatherCategory.Indoors, new string[6] { "Caves", "CavesHildir", "Crypt", "CryptHildir", "SunkenCrypt", "InfectedMine" });
			return t;
			void Add(WeatherCategory c, params string[] names)
			{
				foreach (string key in names)
				{
					t.Add(key, c);
				}
			}
		}

		private static Dictionary<string, string> BuildAliases()
		{
			Dictionary<string, string> t = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			Add(" Summer", new string[7] { "Clear", "Misty", "DeepForest Mist", "Mistlands_clear", "Heath clear", "SwampRain", "Swamp" });
			Add(" Fall", new string[2] { "ThunderStorm", "SwampRain" });
			Add(" Winter", new string[14]
			{
				"Rain", "LightRain", "ThunderStorm", "Clear", "Misty", "DeepForest Mist", "SwampRain", "Mistlands_clear", "Mistlands_rain", "Mistlands_thunder",
				"Heath clear", "Snow", "SnowStorm", "Darklands_dark"
			});
			return t;
			void Add(string suffix, params string[] names)
			{
				foreach (string text in names)
				{
					t.Add(text + suffix, text);
				}
			}
		}
	}
	public readonly struct ForecastEntry
	{
		public string Name { get; }

		public float Weight { get; }

		public bool AshlandsOverride { get; }

		public bool DeepnorthOverride { get; }

		public ForecastEntry(string name, float weight, bool ashlandsOverride, bool deepnorthOverride)
		{
			Name = name ?? "";
			Weight = weight;
			AshlandsOverride = ashlandsOverride;
			DeepnorthOverride = deepnorthOverride;
		}
	}
	public readonly struct ForecastChange
	{
		public long Period { get; }

		public long SecondsUntil { get; }

		public string Name { get; }

		public ForecastChange(long period, long secondsUntil, string name)
		{
			Period = period;
			SecondsUntil = secondsUntil;
			Name = name ?? "";
		}
	}
	public readonly struct ForecastLine
	{
		public static ForecastLine None => new ForecastLine(visible: false, "", 0, "", 0, WeatherCategory.Clear);

		public bool Visible { get; }

		public string NameKey { get; }

		public int Minutes { get; }

		public string WindPoint { get; }

		public int WindPercent { get; }

		public WeatherCategory Category { get; }

		public ForecastLine(bool visible, string nameKey, int minutes, string windPoint, int windPercent, WeatherCategory category)
		{
			Visible = visible;
			NameKey = nameKey ?? "";
			Minutes = minutes;
			WindPoint = windPoint ?? "";
			WindPercent = windPercent;
			Category = category;
		}
	}
	public static class WeatherForecast
	{
		public const int MaxAhead = 3;

		public static long Duration(long duration)
		{
			if (duration >= 1)
			{
				return duration;
			}
			return 1L;
		}

		public static long Period(long worldSeconds, long duration)
		{
			if (worldSeconds < 0)
			{
				worldSeconds = 0L;
			}
			return worldSeconds / Duration(duration);
		}

		public static long SecondsUntilChange(long worldSeconds, long duration)
		{
			duration = Duration(duration);
			if (worldSeconds < 0)
			{
				worldSeconds = 0L;
			}
			long num = worldSeconds % duration;
			if (num != 0L)
			{
				return duration - num;
			}
			return duration;
		}

		public static int MinutesUntil(long seconds)
		{
			if (seconds <= 0)
			{
				return 0;
			}
			long num = (seconds + 59) / 60;
			if (num <= int.MaxValue)
			{
				return (int)num;
			}
			return int.MaxValue;
		}

		public static float WeightSum(IReadOnlyList<ForecastEntry>? entries)
		{
			float num = 0f;
			if (entries == null)
			{
				return 0f;
			}
			foreach (ForecastEntry entry in entries)
			{
				if (!entry.AshlandsOverride && !entry.DeepnorthOverride)
				{
					num += entry.Weight;
				}
			}
			if (float.IsNaN(num) || float.IsInfinity(num) || num < 0f)
			{
				return 0f;
			}
			return num;
		}

		public static IReadOnlyList<ForecastEntry> Filtered(IReadOnlyList<ForecastEntry>? entries, Func<string, bool>? allows, string? fallback)
		{
			if (entries == null)
			{
				entries = Array.Empty<ForecastEntry>();
			}
			if (allows == null)
			{
				return entries;
			}
			bool flag = false;
			List<ForecastEntry> list = new List<ForecastEntry>();
			foreach (ForecastEntry entry in entries)
			{
				if (allows(entry.Name ?? ""))
				{
					list.Add(entry);
				}
				else
				{
					flag = true;
				}
			}
			if (!flag)
			{
				return entries;
			}
			if (list.Count > 0)
			{
				return list;
			}
			if (string.IsNullOrEmpty(fallback))
			{
				return entries;
			}
			return new ForecastEntry[1]
			{
				new ForecastEntry(fallback, 1f, ashlandsOverride: false, deepnorthOverride: false)
			};
		}

		public static

plugins/Cairn/Cairn.dll

Decompiled 19 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExtraPotions.Cairn.Config;
using ExtraPotions.Cairn.Conversion;
using ExtraPotions.Cairn.Hud;
using ExtraPotions.Cairn.Integration;
using ExtraPotions.Cairn.Localization;
using ExtraPotions.Cairn.Radius;
using ExtraPotions.Cairn.Skill;
using ExtraPotions.Cairn.Visibility;
using ExtraPotions.Cairn.WorldTime;
using ExtraPotions.Meadworks.Contracts;
using ExtraPotions.Meadworks.Crucible;
using ExtraPotions.Meadworks.Crucible.UI;
using HarmonyLib;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.PostProcessing;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_postprocessing")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ExtraPotions")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (C) 2026 expDARE (ExtraPotions Meadworks)")]
[assembly: AssemblyFileVersion("0.1.18.0")]
[assembly: AssemblyInformationalVersion("0.1.18+fatal: not a git repository (or any of the parent directories): .git")]
[assembly: AssemblyProduct("Cairn")]
[assembly: AssemblyTitle("Cairn")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.18.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 ExtraPotions.Cairn.Runtime
{
	public sealed class CairnConfig
	{
		private const string Product = "com.meadworks.cairn";

		private readonly ConfigFile file;

		private readonly Dictionary<CairnSetting, ConfigEntryBase> entries = new Dictionary<CairnSetting, ConfigEntryBase>();

		public SkillValues Skill => new SkillValues(Get<bool>(Skill.Enabled), Get<float>(Skill.ExperiencePerSquareKilometre), Get<float>(Skill.LocationDiscoveryExperience), Get<float>(Skill.NewBiomeExperience), Get<float>(Skill.LandRadiusAt100), Get<float>(Skill.WeatherPenaltyReductionAt100), Get<float>(Skill.NightPenaltyReductionAt100), Get<int>(Skill.VantageLevel), Get<float>(Skill.VantageCooldown));

		private CairnConfig(ConfigFile file)
		{
			this.file = file;
			bool saveOnConfigSet = file.SaveOnConfigSet;
			file.SaveOnConfigSet = false;
			try
			{
				foreach (CairnSetting item in CairnSettings.All)
				{
					BindSetting(item);
				}
			}
			finally
			{
				file.SaveOnConfigSet = saveOnConfigSet;
			}
			file.Save();
		}

		public static CairnConfig Bind(ConfigFile file, MeadworksLog log)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if (file == null)
			{
				throw new ArgumentNullException("file");
			}
			if (log == null)
			{
				throw new ArgumentNullException("log");
			}
			CairnConfig cairnConfig = new CairnConfig(file);
			foreach (KeyValuePair<CairnSetting, ConfigEntryBase> item in cairnConfig.entries.Where<KeyValuePair<CairnSetting, ConfigEntryBase>>((KeyValuePair<CairnSetting, ConfigEntryBase> p) => (int)p.Key.Scope != 0 && !p.Key.Hidden))
			{
				MeadworksBlockedOptions.Track("com.meadworks.cairn", item.Value, Map(item.Key.Scope), true);
			}
			log.Verbose("Configuration bound: " + Count((SettingScope)0) + " Local, " + Count((SettingScope)1) + " ServerAuthoritative, " + CairnSettings.All.Count((CairnSetting s) => s.Hidden) + " hidden.");
			log.Info("Retired setting retained and ignored: " + ((CairnSetting)Radius.ShowRadiusInputs).Id + ". Its saved value is preserved.");
			return cairnConfig;
		}

		public static ConfigScope Map(SettingScope scope)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected I4, but got Unknown
			return (ConfigScope)((int)scope switch
			{
				0 => 0, 
				1 => 1, 
				2 => 2, 
				_ => throw new ArgumentException("Unknown scope.", "scope"), 
			});
		}

		public ConfigEntryBase Entry(CairnSetting setting)
		{
			if (!entries.TryGetValue(setting ?? throw new ArgumentNullException("setting"), out ConfigEntryBase value))
			{
				throw new ArgumentException("Not a Cairn setting.", "setting");
			}
			return value;
		}

		public T Get<T>(CairnSetting<T> setting)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			//IL_0012: 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)
			if (Entry((CairnSetting)(object)setting) is ConfigEntry<KeyboardShortcut> val)
			{
				KeyboardShortcut value = val.Value;
				return setting.Normalize((T)(object)((KeyboardShortcut)(ref value)).Serialize());
			}
			ConfigEntry<T> val2 = (ConfigEntry<T>)(object)Entry((CairnSetting)(object)setting);
			if ((int)((CairnSetting)setting).Scope == 1)
			{
				return setting.Normalize(MeadworksConfig.Effective<T>(val2, "com.meadworks.cairn", (ConfigScope)1, setting.Default, true));
			}
			return setting.Normalize(val2.Value);
		}

		public ConfigEntry<KeyboardShortcut> ShortcutEntry(CairnSetting<string> setting)
		{
			return (Entry((CairnSetting)(object)setting) as ConfigEntry<KeyboardShortcut>) ?? throw new ArgumentException(((CairnSetting)setting).Id + " is not a keyboard shortcut.", "setting");
		}

		public RadiusValues Radius(bool held)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			RadiusValues result = default(RadiusValues);
			((RadiusValues)(ref result))..ctor(Get<float>(Radius.MinimumRadius), Get<float>(Radius.MaximumRadius), Get<float>(Radius.LandExploreRadius), Get<float>(Radius.SeaExploreRadius), Get<float>(Radius.AltitudeRadiusBonus), Get<float>(Radius.ForestRadiusPenalty), Get<float>(Radius.DaylightRadiusScale), Get<float>(Radius.WeatherRadiusScale));
			if (!held)
			{
				return result;
			}
			return ((RadiusValues)(ref result)).Held();
		}

		public bool Removes(VisibilityEffect effect, bool held)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return VisibilityPolicy.Removes(effect, Get<bool>(Visibility.Remove(effect)), Get<bool>(VisibilityServer.Allow(effect)), held);
		}

		public float Strength(CairnSetting<float> setting, bool held, params VisibilityEffect[] gates)
		{
			//IL_000d: 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)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			bool flag = true;
			bool flag2 = false;
			foreach (VisibilityEffect val in gates)
			{
				flag &= Get<bool>(VisibilityServer.Allow(val));
				flag2 |= VisibilityPolicy.IsGateLike(val);
			}
			return VisibilityPolicy.Strength(Get<float>(setting), flag, held, flag2);
		}

		public void Shutdown()
		{
			foreach (ConfigEntryBase value in entries.Values)
			{
				MeadworksBlockedOptions.Untrack(value);
			}
			entries.Clear();
		}

		private void BindSetting(CairnSetting setting)
		{
			//IL_0061: 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)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntryBase value;
			if (!(setting is CairnSetting<string> val))
			{
				if (!(setting is CairnSetting<bool> setting2))
				{
					if (!(setting is CairnSetting<int> val2))
					{
						if (!(setting is CairnSetting<float> val3))
						{
							throw new NotSupportedException(setting.Id + ": unsupported value type " + setting.ValueType.Name + ".");
						}
						value = (ConfigEntryBase)(object)Bind<float>(val3, (AcceptableValueBase?)(object)new AcceptableValueRange<float>((float)((CairnSetting)val3).Minimum, (float)((CairnSetting)val3).Maximum));
					}
					else
					{
						value = (ConfigEntryBase)(object)Bind<int>(val2, (AcceptableValueBase?)(object)new AcceptableValueRange<int>((int)((CairnSetting)val2).Minimum, (int)((CairnSetting)val2).Maximum));
					}
				}
				else
				{
					value = (ConfigEntryBase)(object)Bind<bool>(setting2, null);
				}
			}
			else if (CairnSettings.KeyboardShortcuts.Contains(val))
			{
				value = (ConfigEntryBase)(object)MeadworksConfig.Bind<KeyboardShortcut>(file, ((CairnSetting)val).Section, ((CairnSetting)val).Key, ParseShortcut(val.Default), Describe<KeyboardShortcut>((CairnSetting)(object)val, null), Map(((CairnSetting)val).Scope));
			}
			else
			{
				CairnSetting<string> setting3 = val;
				value = (ConfigEntryBase)(object)Bind<string>(setting3, null);
			}
			entries.Add(setting, value);
		}

		private ConfigDescription Describe<T>(CairnSetting setting, AcceptableValueBase? acceptable)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Expected O, but got Unknown
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Expected O, but got Unknown
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Expected O, but got Unknown
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Expected O, but got Unknown
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Expected O, but got Unknown
			ConfigDependency val = null;
			if ((object)setting == Hud.ShowDay || (object)setting == Hud.ShowTime || (object)setting == Hud.ShowWeather || (object)setting == Hud.ShowForecast || (object)setting == Hud.ShowCompass || (object)setting == Hud.ShowHeading || (object)setting == Hud.ShowMarkers || (object)setting == Hud.TempestWarnings || (object)setting == Radius.ShowRadius)
			{
				val = new ConfigDependency((Func<bool>)(() => Get<bool>(Hud.Enabled)), (Func<string>)(() => "Requires " + ((CairnSetting)Hud.Enabled).Section + ": " + ((CairnSetting)Hud.Enabled).Key + "."), (Func<bool>)null);
			}
			if ((object)setting == Radius.MinimumRadius || (object)setting == Radius.MaximumRadius || (object)setting == Radius.LandExploreRadius || (object)setting == Radius.SeaExploreRadius || (object)setting == Radius.AltitudeRadiusBonus || (object)setting == Radius.ForestRadiusPenalty || (object)setting == Radius.DaylightRadiusScale || (object)setting == Radius.WeatherRadiusScale)
			{
				val = new ConfigDependency((Func<bool>)(() => Get<bool>(Radius.Enabled)), (Func<string>)(() => "Requires " + ((CairnSetting)Radius.Enabled).Section + ": " + ((CairnSetting)Radius.Enabled).Key + "."), (Func<bool>)null);
			}
			if ((object)setting == Skill.ExperiencePerSquareKilometre || (object)setting == Skill.LocationDiscoveryExperience || (object)setting == Skill.NewBiomeExperience || (object)setting == Skill.LandRadiusAt100 || (object)setting == Skill.WeatherPenaltyReductionAt100 || (object)setting == Skill.NightPenaltyReductionAt100 || (object)setting == Skill.VantageLevel || (object)setting == Skill.VantageCooldown)
			{
				val = new ConfigDependency((Func<bool>)(() => Get<bool>(Skill.Enabled)), (Func<string>)(() => "Requires " + ((CairnSetting)Skill.Enabled).Section + ": " + ((CairnSetting)Skill.Enabled).Key + "."), (Func<bool>)null);
			}
			if ((object)setting == Hud.Use24Hour)
			{
				val = new ConfigDependency((Func<bool>)(() => Get<bool>(Hud.Enabled) && Get<bool>(Hud.ShowTime)), (Func<string>)(() => "Requires HUD: Enabled and " + ((CairnSetting)Hud.ShowTime).Key + "."), (Func<bool>)null);
			}
			if ((object)setting == Map.ShowAllNamesKey || (object)setting == Map.HoverScale)
			{
				val = new ConfigDependency((Func<bool>)(() => Get<bool>(Map.TidyPins)), (Func<string>)(() => "Requires 7 - Map: " + ((CairnSetting)Map.TidyPins).Key + "."), (Func<bool>)null);
			}
			if ((object)setting == Hud.StripDegrees || (object)setting == Hud.CompassWidth)
			{
				val = new ConfigDependency((Func<bool>)(() => Get<bool>(Hud.Enabled) && Get<bool>(Hud.ShowCompass)), (Func<string>)(() => "Requires HUD: Enabled and " + ((CairnSetting)Hud.ShowCompass).Key + "."), (Func<bool>)null);
			}
			if ((object)setting == Hud.MaxMarkers || (object)setting == Hud.MaxDistance)
			{
				val = new ConfigDependency((Func<bool>)(() => Get<bool>(Hud.Enabled) && Get<bool>(Hud.ShowMarkers)), (Func<string>)(() => "Requires HUD: Enabled and " + ((CairnSetting)Hud.ShowMarkers).Key + "."), (Func<bool>)null);
			}
			ConfigPresentation<T> val2 = new ConfigPresentation<T>("com.meadworks.cairn", (Func<ConfigEntry<T>, string, ConfigPresentationText>)delegate
			{
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Expected O, but got Unknown
				if (CairnText.Translations != null)
				{
					string text = CairnText.SettingName(setting);
					string text2 = CairnText.SettingHelp(setting);
					string text3 = (((object)setting == Map.TidyPins) ? "tidy_pins_description" : CairnTextKeys.SettingHelp(setting));
					if (text == CairnTextKeys.Setting(setting) || text == "setting_remove" || text == "setting_allow_removing")
					{
						text = null;
					}
					if (text2 == text3 || text2 == "help_remove" || text2 == "help_allow_removing")
					{
						text2 = null;
					}
					return new ConfigPresentationText(text, (string)null, text2);
				}
				return (ConfigPresentationText?)null;
			});
			return new ConfigDescription(setting.Description, acceptable, (val != null) ? new object[2] { val, val2 } : new object[1] { val2 });
		}

		private ConfigEntry<T> Bind<T>(CairnSetting<T> setting, AcceptableValueBase? acceptable)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0087: 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_0055: 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)
			if ((int)((CairnSetting)setting).Scope == 2)
			{
				return MeadworksConfig.BindCheat<T>(file, ((CairnSetting)setting).Section, ((CairnSetting)setting).Key, setting.Safe, ((CairnSetting)setting).Description, acceptable);
			}
			if (((CairnSetting)setting).Hidden)
			{
				return MeadworksConfig.BindHidden<T>(file, ((CairnSetting)setting).Section, ((CairnSetting)setting).Key, setting.Default, ((CairnSetting)setting).Description, Map(((CairnSetting)setting).Scope), acceptable);
			}
			return MeadworksConfig.Bind<T>(file, ((CairnSetting)setting).Section, ((CairnSetting)setting).Key, setting.Default, Describe<T>((CairnSetting)(object)setting, acceptable), Map(((CairnSetting)setting).Scope));
		}

		public static KeyboardShortcut ParseShortcut(string text)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0021: 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)
			text = (text ?? "").Trim();
			if (text.Length == 0)
			{
				return KeyboardShortcut.Empty;
			}
			try
			{
				return KeyboardShortcut.Deserialize(text);
			}
			catch (Exception)
			{
				return KeyboardShortcut.Empty;
			}
		}

		private static int Count(SettingScope scope)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return CairnSettings.All.Count((CairnSetting s) => s.Scope == scope && !s.Hidden);
		}
	}
	public static class CairnForecast
	{
		private static class TempestGate
		{
			private static Type? type;

			private static bool found;

			private static MethodInfo? allows;

			private static MethodInfo? fallback;

			private static Func<string, bool>? allowsCall;

			private static void Look()
			{
				if (found)
				{
					return;
				}
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					if (string.Equals(assembly.GetName().Name, "Tempest", StringComparison.Ordinal))
					{
						type = assembly.GetType("ExtraPotions.Tempest.Runtime.TempestFilter");
						break;
					}
				}
				found = AssemblyScan.CacheMiss();
				if (!(type == null))
				{
					allows = type.GetMethod("Allows", BindingFlags.Static | BindingFlags.Public);
					fallback = type.GetMethod("Fallback", BindingFlags.Static | BindingFlags.Public);
				}
			}

			public static Func<string, bool>? Allows()
			{
				Look();
				if (allows == null)
				{
					return null;
				}
				return delegate(string name)
				{
					try
					{
						return (bool)allows.Invoke(null, new object[1] { name });
					}
					catch (Exception)
					{
						return true;
					}
				};
			}

			public static string? FallbackName(EnvMan env, BiomeSector biome)
			{
				Look();
				if (fallback == null)
				{
					return null;
				}
				try
				{
					object obj = fallback.Invoke(null, new object[2] { env, biome });
					return (obj?.GetType().GetField("m_name"))?.GetValue(obj) as string;
				}
				catch (Exception)
				{
					return null;
				}
			}
		}

		private static ForecastLine cached = ForecastLine.None;

		private static long cachedPeriod = long.MinValue;

		private static int cachedX;

		private static int cachedZ;

		private static bool cachedAsh;

		private static bool cachedDeep;

		private static bool cacheValid;

		private static bool warned;

		private static float nextRoll;

		public static ForecastLine Current { get; private set; } = ForecastLine.None;

		public static ForecastLine Read(EnvMan? env, bool enabled, bool scheduleFree)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			if (!enabled || !scheduleFree || (Object)(object)env == (Object)null)
			{
				cacheValid = false;
				Current = ForecastLine.None;
				return Current;
			}
			try
			{
				Current = Predict(env);
			}
			catch (Exception ex)
			{
				cacheValid = false;
				Current = ForecastLine.None;
				if (!warned)
				{
					warned = true;
					Debug.LogWarning((object)("Cairn forecast unavailable: " + ex.GetType().Name + " " + ex.Message));
				}
			}
			return Current;
		}

		public static string Text(ForecastLine line)
		{
			if (!((ForecastLine)(ref line)).Visible)
			{
				return "";
			}
			string text = CairnText.Text(((ForecastLine)(ref line)).NameKey);
			string text2 = ((ForecastLine)(ref line)).Minutes.ToString(CultureInfo.InvariantCulture);
			if (((ForecastLine)(ref line)).WindPoint.Length == 0)
			{
				return CairnText.Format("hud_forecast", text, text2);
			}
			string text3 = CairnText.Text(CairnTextKeys.CompassPoint(((ForecastLine)(ref line)).WindPoint)) + " " + ((ForecastLine)(ref line)).WindPercent.ToString(CultureInfo.InvariantCulture) + "%";
			return CairnText.Format("hud_forecast_wind", text, text2, text3);
		}

		private static ForecastLine Predict(EnvMan env)
		{
			//IL_0024: 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_0048: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			ZNet instance = ZNet.instance;
			Camera mainCamera = Utils.GetMainCamera();
			if ((Object)(object)instance == (Object)null || (Object)(object)mainCamera == (Object)null)
			{
				return ForecastLine.None;
			}
			if (Held(env, Player.m_localPlayer))
			{
				return ForecastLine.None;
			}
			Vector3 position = ((Component)mainCamera).transform.position;
			bool flag = WorldGenerator.IsAshlands(position.x, position.z);
			bool flag2 = WorldGenerator.IsDeepnorth(position.x, position.y);
			long num = (long)instance.GetTimeSeconds();
			long environmentDuration = env.m_environmentDuration;
			long num2 = WeatherForecast.Period(num, environmentDuration);
			int num3 = (int)(position.x / 64f);
			int num4 = (int)(position.z / 64f);
			int num5 = WeatherForecast.MinutesUntil(WeatherForecast.SecondsUntilChange(num, environmentDuration));
			if (cacheValid && cachedPeriod == num2 && cachedX == num3 && cachedZ == num4 && cachedAsh == flag && cachedDeep == flag2 && Time.unscaledTime < nextRoll)
			{
				if (!((ForecastLine)(ref cached)).Visible)
				{
					return ForecastLine.None;
				}
				return new ForecastLine(true, ((ForecastLine)(ref cached)).NameKey, num5, ((ForecastLine)(ref cached)).WindPoint, ((ForecastLine)(ref cached)).WindPercent, ((ForecastLine)(ref cached)).Category);
			}
			nextRoll = Time.unscaledTime + 1f;
			cachedPeriod = num2;
			cachedX = num3;
			cachedZ = num4;
			cachedAsh = flag;
			cachedDeep = flag2;
			cacheValid = true;
			BiomeSector biome = env.GetBiome();
			List<EnvEntry> availableEnvironments = env.GetAvailableEnvironments(biome);
			List<ForecastEntry> list = new List<ForecastEntry>();
			if (availableEnvironments != null)
			{
				foreach (EnvEntry item in availableEnvironments)
				{
					if (item != null && !string.IsNullOrEmpty(item.m_environment))
					{
						list.Add(new ForecastEntry(item.m_environment, item.m_weight, item.m_ashlandsOverride, item.m_deepnorthOverride));
					}
				}
			}
			Func<string, bool> func = TempestGate.Allows();
			string text = ((func == null) ? null : TempestGate.FallbackName(env, biome));
			IReadOnlyList<ForecastEntry> readOnlyList = WeatherForecast.Filtered((IReadOnlyList<ForecastEntry>)list, func, text);
			float total = WeatherForecast.WeightSum(readOnlyList);
			IReadOnlyList<ForecastChange> readOnlyList2 = WeatherForecast.Upcoming(num, environmentDuration, 1, (IReadOnlyList<ForecastEntry>)list, flag, flag2, (Func<long, float>)((long next) => Roll(next, total)), func, text);
			if (readOnlyList2.Count == 0)
			{
				cached = ForecastLine.None;
				return cached;
			}
			ForecastChange val = readOnlyList2[0];
			EnvSetup val2 = Find(env, ((ForecastChange)(ref val)).Name);
			WeatherCategory val3 = WeatherCategories.Of(((ForecastChange)(ref val)).Name, val2?.m_fogDensityDay ?? 0f, val2?.m_isWet ?? false, false);
			string text2 = WeatherCategories.EventToken(((ForecastChange)(ref val)).Name);
			string text3 = ((text2 != null) ? CairnTextKeys.TempestToken(text2) : CairnTextKeys.Weather(val3));
			string text4 = "";
			int num6 = 0;
			if (val2 != null)
			{
				long time = ((num < 0) ? ((ForecastChange)(ref val)).SecondsUntil : (num + ((ForecastChange)(ref val)).SecondsUntil));
				ValueTuple<float, float> valueTuple = WeatherForecast.Wind(val2.m_windMin, val2.m_windMax, (IReadOnlyList<float>)SampleWind(time, env.m_windPeriodDuration));
				text4 = WeatherForecast.WindPoint(valueTuple.Item1);
				num6 = WeatherForecast.WindPercent(valueTuple.Item2);
			}
			cached = new ForecastLine(true, text3, num5, text4, num6, val3);
			return cached;
		}

		private static bool Held(EnvMan env, Player? player)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			EnvSetup currentEnvironment = env.GetCurrentEnvironment();
			if (currentEnvironment != null && WeatherCategories.EventToken(currentEnvironment.m_name) != null)
			{
				return true;
			}
			if (Allowed(env.m_debugEnv) || Allowed(env.m_forceEnv))
			{
				return true;
			}
			if ((Object)(object)player != (Object)null && ((Character)player).InIntro() && Allowed(env.m_introEnvironment))
			{
				return true;
			}
			RandEventSystem instance = RandEventSystem.instance;
			if ((Object)(object)instance != (Object)null && Allowed(instance.GetEnvOverride()))
			{
				return true;
			}
			if ((Object)(object)player != (Object)null && WorldGenerator.instance != null)
			{
				List<AltBiome> altBiomes = WorldGenerator.instance.GetBiomeSector(((Component)player).transform.position, false).AltBiomes;
				if (altBiomes != null)
				{
					foreach (AltBiome item in altBiomes)
					{
						if (item != null && Allowed(item.m_forceEnvironment))
						{
							return true;
						}
					}
				}
			}
			PersistentEventSystem instance2 = PersistentEventSystem.instance;
			if ((Object)(object)instance2 != (Object)null && Allowed(instance2.GetEnvironmentOverride()))
			{
				return true;
			}
			return Allowed(EnvZone.GetEnvironment());
		}

		private static bool Allowed(string? name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			return TempestGate.Allows()?.Invoke(name) ?? true;
		}

		private static EnvSetup? Find(EnvMan env, string name)
		{
			List<EnvSetup> environments = env.m_environments;
			if (environments == null)
			{
				return null;
			}
			for (int i = 0; i < environments.Count; i++)
			{
				EnvSetup val = environments[i];
				if (val != null && string.Equals(val.m_name, name, StringComparison.Ordinal))
				{
					return val;
				}
			}
			return null;
		}

		private static float Roll(long period, float total)
		{
			//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_002a: Unknown result type (might be due to invalid IL or missing references)
			State state = Random.state;
			try
			{
				Random.InitState((int)period);
				return (total > 0f) ? Random.Range(0f, total) : 0f;
			}
			finally
			{
				Random.state = state;
			}
		}

		private static float[] SampleWind(long time, long windDuration)
		{
			//IL_0007: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			float[] array = new float[8];
			State state = Random.state;
			try
			{
				int[] array2 = new int[4] { 1, 2, 4, 8 };
				for (int i = 0; i < array2.Length; i++)
				{
					Random.InitState(WeatherForecast.WindSeed(time, windDuration, array2[i]));
					array[i * 2] = Random.value;
					array[i * 2 + 1] = Random.value;
				}
				return array;
			}
			finally
			{
				Random.state = state;
			}
		}
	}
	public static class CairnHud
	{
		private const int IconSize = 15;

		private static readonly Color Cream = new Color(1f, 0.9f, 0.68f, 1f);

		private static readonly Color Gold = new Color(0.86f, 0.7f, 0.4f, 1f);

		private static readonly Color Bronze = new Color(0.72f, 0.5f, 0.26f, 0.9f);

		private static KitHudPanel? panel;

		private static Transform? owner;

		private static readonly Dictionary<HudRow, TMP_Text> labels = new Dictionary<HudRow, TMP_Text>();

		private static readonly Dictionary<HudRow, Image?> plates = new Dictionary<HudRow, Image>();

		private static readonly Image?[] capRivets = (Image?[])(object)new Image[2];

		private const int CapRivetMinHeight = 34;

		private static TMP_Text? clockText;

		private static TMP_Text? weatherText;

		private static Image? clockIcon;

		private static Image? weatherIcon;

		private static Image? eventIcon;

		private static Image? divider;

		private static Image? pointer;

		private static readonly List<TMP_Text> ticks = new List<TMP_Text>();

		private static readonly List<Image> marks = new List<Image>();

		private static readonly List<(Image Icon, TMP_Text Distance)> markers = new List<(Image, TMP_Text)>();

		private static readonly Dictionary<HudIcon, Sprite> icons = new Dictionary<HudIcon, Sprite>();

		private static bool toggledOff;

		private static bool ownsSleep;

		private static bool showingSleep;

		private static (int ParentWidth, int ParentHeight, int Width, int Height)? placement;

		private static float nextMarkers;

		private static Player? character;

		private static long world;

		private static List<PinData> selected = new List<PinData>();

		private static HudOptions drawnOptions;

		private static IReadOnlyList<HudRow>? drawnRows;

		private static HudSize drawnSize;

		private static int drawnCompassWidth;

		private static readonly List<HudRow> extraRows = new List<HudRow>();

		private static (IReadOnlyList<HudRow>? Rows, int Width, int Day, int Hour, int Minute, bool Use24, bool Night, WeatherCategory Category, string? Language, long Revision, string? Event, bool Forecast, string? ForecastName, int ForecastMinutes, string? ForecastWind, int ForecastPercent, WeatherCategory ForecastCategory) statusDrawn;

		private static (IReadOnlyList<HudRow>? Rows, int Width, bool Plate) stripDrawn;

		private static (IReadOnlyList<HudRow>? Rows, int Width, int Degrees, string? Point, string? Language, long Revision, bool Plate) headingDrawn;

		private static (IReadOnlyList<HudRow>? Rows, int Width, int Plates) extrasDrawn;

		private static (bool Has, float Radius, float Base, float Multiplier, float Light, float Weather, float Altitude, float Location, string? Language, long Revision)? radiusDrawn;

		private static (bool Has, float Radius, float Base, float Multiplier, float Light, float Weather, float Altitude, float Location, string? Language, long Revision)? inputsDrawn;

		private static (TempestLineKind Kind, string? TextKey, string? EventKey, string? Countdown, string? Language, long Revision, IReadOnlyList<HudRow>? Rows, int Width)? tempestDrawn;

		private static (bool Visible, string? Sleeping, string? Players, string? Skip, string? Boost, string? Language, long Revision)? sleepDrawn;

		private static (bool Show, IReadOnlyList<HudRow>? Rows, int Width, int Degrees, float Heading, string? Language, long Revision, bool Markers, List<PinData>? Selected, float X, float Z, int Max, float MaxDistance) compassDrawn;

		private static readonly List<(float X, float Z, Sprite? Icon, bool IconAlive, PinType Type)> drawnPins = new List<(float, float, Sprite, bool, PinType)>();

		private static readonly List<float> pinOffsets = new List<float>();

		private static readonly Dictionary<string, PadButton[]?> chords = new Dictionary<string, PadButton[]>(StringComparer.Ordinal);

		private static string? toggleKeyText;

		private static KeyboardShortcut toggleKey = KeyboardShortcut.Empty;

		private static bool toggleKeyValid;

		private static readonly Tuple<bool, float, float, float, float> NotShown = Tuple.Create(item1: false, 0f, 0f, 0f, 0f);

		private static readonly Color MoonTint = new Color(0.8f, 0.84f, 0.92f, 1f);

		internal static bool ToggledOff => toggledOff;

		public static Tuple<bool, float, float, float, float> Occupied()
		{
			KitHudPanel? obj = panel;
			if ((Object)(object)((obj != null) ? obj.Root : null) != (Object)null)
			{
				Transform? obj2 = owner;
				RectTransform val = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null);
				if (val != null)
				{
					return KitHudOccupancy.Measure(val, panel.Root);
				}
			}
			return NotShown;
		}

		public static bool ShowingWeather()
		{
			if (TempestNotice.HudRowDrawn)
			{
				KitHudPanel? obj = panel;
				if ((Object)(object)((obj != null) ? obj.Root : null) != (Object)null)
				{
					return ((Component)panel.Root).gameObject.activeInHierarchy;
				}
			}
			return false;
		}

		public static bool ShowingSleep()
		{
			return showingSleep;
		}

		public static void Tick()
		{
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Invalid comparison between Unknown and I4
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_048e: Unknown result type (might be due to invalid IL or missing references)
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_0495: Unknown result type (might be due to invalid IL or missing references)
			//IL_049c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_051d: Invalid comparison between Unknown and I4
			//IL_0555: Unknown result type (might be due to invalid IL or missing references)
			//IL_055a: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			TempestNotice.HudRowDrawn = false;
			ownsSleep = (showingSleep = false);
			CairnConfig settings = Plugin.Settings;
			Player localPlayer = Player.m_localPlayer;
			object obj;
			if (!((Object)(object)Hud.instance != (Object)null))
			{
				obj = null;
			}
			else
			{
				GameObject rootObject = Hud.instance.m_rootObject;
				obj = ((rootObject != null) ? rootObject.transform : null);
			}
			Transform val = (Transform)obj;
			if (!Plugin.Ready || !Plugin.AllowsUi || settings == null || (Object)(object)localPlayer == (Object)null || (Object)(object)val == (Object)null || !CrucibleUiPlugin.Active || (Object)(object)KitCanvas.Font == (Object)null)
			{
				Hide();
				return;
			}
			long num = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetWorldUID() : 0);
			if ((Object)(object)character != (Object)(object)localPlayer || world != num)
			{
				character = localPlayer;
				world = num;
				toggledOff = false;
				nextMarkers = 0f;
				selected.Clear();
			}
			bool flag = CairnModules.StepAside.SteppedAside((CairnModule)2);
			if (!flag && MeadworksInput.Allows((InputContext)0) && TogglePressed(settings))
			{
				toggledOff = !toggledOff;
			}
			ownsSleep = HudLayout.OwnsSleep(settings.Get<bool>(Hud.Enabled), Plugin.AllowsUi, flag, toggledOff, CairnSleep.Reading);
			bool hudBlocked = KitWindows.HudBlocked;
			bool flag2 = hudBlocked || Minimap.IsOpen() || InventoryGui.IsVisible() || Menu.IsVisible() || StoreGui.IsVisible() || TextInput.IsVisible() || CairnSettingsWindow.IsOpen;
			if (ownsSleep && !flag2)
			{
				showingSleep = CairnMinimapEffects.Draw(val);
			}
			else
			{
				CairnMinimapEffects.Hide();
				showingSleep = false;
			}
			bool flag3 = hudBlocked || Hud.IsUserHidden() || Minimap.IsOpen() || InventoryGui.IsVisible() || Menu.IsVisible() || CairnSettingsWindow.IsOpen;
			if (!HudLayout.Visible(settings.Get<bool>(Hud.Enabled), Plugin.AllowsUi, flag, toggledOff, flag3))
			{
				HideHud();
				return;
			}
			if (panel != null && ((Object)(object)panel.Root == (Object)null || (Object)(object)owner != (Object)(object)val))
			{
				DisposePanel();
			}
			if (panel == null)
			{
				Build(val);
			}
			if (panel == null)
			{
				return;
			}
			EnvMan instance = EnvMan.instance;
			bool enabled = settings.Get<bool>(Hud.ShowForecast);
			TempestLine line = CairnTempest.Line;
			ForecastLine val2 = CairnForecast.Read(instance, enabled, (int)((TempestLine)(ref line)).Kind == 0);
			bool num2 = settings.Get<bool>(Hud.ShowDay);
			bool num3 = settings.Get<bool>(Hud.ShowTime);
			bool num4 = settings.Get<bool>(Hud.ShowWeather);
			bool num5 = settings.Get<bool>(Hud.ShowCompass);
			bool num6 = settings.Get<bool>(Hud.ShowHeading);
			bool num7 = settings.Get<bool>(Radius.ShowRadius);
			line = CairnTempest.Line;
			HudOptions val3 = default(HudOptions);
			((HudOptions)(ref val3))..ctor(num2, num3, num4, num5, num6, num7, false, ((TempestLine)(ref line)).Kind, false, ((ForecastLine)(ref val2)).Visible);
			int num8 = settings.Get<int>(Hud.CompassWidth);
			if (drawnRows == null || !SameOptions(val3, drawnOptions) || num8 != drawnCompassWidth)
			{
				drawnOptions = val3;
				drawnCompassWidth = num8;
				drawnRows = HudLayout.Rows(val3);
				drawnSize = HudLayout.Size(drawnRows, num8);
			}
			IReadOnlyList<HudRow> readOnlyList = drawnRows;
			if (readOnlyList.Count == 0)
			{
				HideHud();
				return;
			}
			HudSize val4 = drawnSize;
			int num9 = (((HudOptions)(ref val3)).ShowRadiusInputs ? Math.Max(((HudSize)(ref val4)).Width, 640) : ((HudSize)(ref val4)).Width);
			panel.Root.sizeDelta = new Vector2((float)num9, (float)((HudSize)(ref val4)).Height);
			RectTransform val5 = (RectTransform)(object)((val is RectTransform) ? val : null);
			float num10;
			Rect rect;
			if (!((Object)(object)val5 != (Object)null))
			{
				num10 = Screen.width;
			}
			else
			{
				rect = val5.rect;
				num10 = ((Rect)(ref rect)).width;
			}
			int num11 = Mathf.RoundToInt(num10);
			float num12;
			if (!((Object)(object)val5 != (Object)null))
			{
				num12 = Screen.height;
			}
			else
			{
				rect = val5.rect;
				num12 = ((Rect)(ref rect)).height;
			}
			int item = Mathf.RoundToInt(num12);
			(int, int) tuple = HudLayout.Home(num11, Mathf.CeilToInt((float)num9 * 1.3333334f));
			(int, int, int, int) tuple2 = (num11, item, num9, ((HudSize)(ref val4)).Height);
			if (placement.HasValue)
			{
				(int, int, int, int) value = placement.Value;
				(int, int, int, int) tuple3 = tuple2;
				if (value.Item1 == tuple3.Item1 && value.Item2 == tuple3.Item2 && value.Item3 == tuple3.Item3 && value.Item4 == tuple3.Item4)
				{
					goto IL_0462;
				}
			}
			panel.SetPosition(new Vector2((float)tuple.Item1, (float)tuple.Item2));
			placement = tuple2;
			goto IL_0462;
			IL_0462:
			EnvMan env = instance;
			Transform transform = ((Component)localPlayer).transform;
			Vector3 val6 = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform.forward : transform.forward);
			float heading = Compass.Heading(val6.x, val6.z);
			string language = CairnText.Language;
			long revision = CairnText.Revision;
			DrawStatus(readOnlyList, val3, num9, env, localPlayer, settings, language, revision);
			DrawStrip(readOnlyList, val3, heading, num9);
			DrawHeading(readOnlyList, heading, num9, language, revision);
			DrawExtras(readOnlyList, num9, language, revision);
			DrawCompass(((HudOptions)(ref val3)).ShowCompass, readOnlyList, heading, num9 - 44, num9, localPlayer, settings, language, revision);
			panel.Update(true, (int)ZCursor.LockState != 1 && ZCursor.IsVisible, 1.3333334f, 0f);
			bool activeInHierarchy = ((Component)panel.Root).gameObject.activeInHierarchy;
			bool num13 = settings.Get<bool>(Hud.TempestWarnings);
			line = CairnTempest.Line;
			TempestNotice.HudRowDrawn = WeatherDisplayCapability.Showing(activeInHierarchy, num13, ((TempestLine)(ref line)).Kind);
		}

		private static bool SameOptions(HudOptions a, HudOptions b)
		{
			//IL_0078: 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)
			if (((HudOptions)(ref a)).ShowDay == ((HudOptions)(ref b)).ShowDay && ((HudOptions)(ref a)).ShowTime == ((HudOptions)(ref b)).ShowTime && ((HudOptions)(ref a)).ShowWeather == ((HudOptions)(ref b)).ShowWeather && ((HudOptions)(ref a)).ShowCompass == ((HudOptions)(ref b)).ShowCompass && ((HudOptions)(ref a)).ShowHeading == ((HudOptions)(ref b)).ShowHeading && ((HudOptions)(ref a)).ShowRadius == ((HudOptions)(ref b)).ShowRadius && ((HudOptions)(ref a)).ShowRadiusInputs == ((HudOptions)(ref b)).ShowRadiusInputs && ((HudOptions)(ref a)).Tempest == ((HudOptions)(ref b)).Tempest && ((HudOptions)(ref a)).Sleep == ((HudOptions)(ref b)).Sleep)
			{
				return ((HudOptions)(ref a)).Forecast == ((HudOptions)(ref b)).Forecast;
			}
			return false;
		}

		private static bool PlateReady(HudRow row)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (plates.TryGetValue(row, out Image value))
			{
				return (Object)(object)value != (Object)null;
			}
			return false;
		}

		private static void Redraw()
		{
			statusDrawn = default((IReadOnlyList<HudRow>, int, int, int, int, bool, bool, WeatherCategory, string, long, string, bool, string, int, string, int, WeatherCategory));
			stripDrawn = default((IReadOnlyList<HudRow>, int, bool));
			headingDrawn = default((IReadOnlyList<HudRow>, int, int, string, string, long, bool));
			extrasDrawn = default((IReadOnlyList<HudRow>, int, int));
			compassDrawn = default((bool, IReadOnlyList<HudRow>, int, int, float, string, long, bool, List<PinData>, float, float, int, float));
			radiusDrawn = (inputsDrawn = null);
			tempestDrawn = null;
			sleepDrawn = null;
			drawnPins.Clear();
		}

		private static void DrawStatus(IReadOnlyList<HudRow> rows, HudOptions options, int panelWidth, EnvMan? env, Player player, CairnConfig settings, string language, long revision)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_0596: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_068f: Unknown result type (might be due to invalid IL or missing references)
			//IL_069f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0698: Unknown result type (might be due to invalid IL or missing references)
			//IL_0750: Unknown result type (might be due to invalid IL or missing references)
			//IL_074a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0755: Unknown result type (might be due to invalid IL or missing references)
			//IL_076a: Unknown result type (might be due to invalid IL or missing references)
			//IL_078e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0792: Unknown result type (might be due to invalid IL or missing references)
			//IL_0797: Unknown result type (might be due to invalid IL or missing references)
			//IL_079e: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a3: Invalid comparison between Unknown and I4
			//IL_07ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a7: Unknown result type (might be due to invalid IL or missing references)
			int num = (((Object)(object)env != (Object)null) ? env.GetCurrentDay() : 0);
			float num2 = (((Object)(object)env != (Object)null) ? env.GetDayFraction() : 0f);
			ValueTuple<int, int> valueTuple = Clock.Parts(num2);
			int item = valueTuple.Item1;
			int item2 = valueTuple.Item2;
			bool flag = settings.Get<bool>(Hud.Use24Hour);
			bool flag2 = EnvMan.IsNight();
			EnvSetup val = (((Object)(object)env != (Object)null) ? env.GetCurrentEnvironment() : null);
			float num3 = ((val == null) ? 0f : (flag2 ? val.m_fogDensityNight : val.m_fogDensityDay));
			WeatherCategory val2 = WeatherCategories.Of(val?.m_name, num3, val?.m_isWet ?? false, ((Character)player).InInterior());
			(string, TempestGlyph)? tuple = TempestWarning.StatusEvent(val2, val?.m_name, CairnTempest.Line);
			string text = tuple?.Item1;
			ForecastLine current = CairnForecast.Current;
			(IReadOnlyList<HudRow>, int, int, int, int, bool, bool, WeatherCategory, string, long, string, bool, string, int, string, int, WeatherCategory) tuple2 = (rows, panelWidth, num, item, item2, flag, flag2, val2, language, revision, text, ((ForecastLine)(ref current)).Visible, ((ForecastLine)(ref current)).NameKey, ((ForecastLine)(ref current)).Minutes, ((ForecastLine)(ref current)).WindPoint, ((ForecastLine)(ref current)).WindPercent, ((ForecastLine)(ref current)).Category);
			(IReadOnlyList<HudRow>, int, int, int, int, bool, bool, WeatherCategory, string, long, string, bool, string, int, string, int, WeatherCategory) tuple3 = tuple2;
			IReadOnlyList<HudRow> item3 = tuple3.Item1;
			int item4 = tuple3.Item2;
			int item5 = tuple3.Item3;
			int item6 = tuple3.Item4;
			int item7 = tuple3.Item5;
			bool item8 = tuple3.Item6;
			bool item9 = tuple3.Item7;
			WeatherCategory item10 = tuple3.Rest.Item1;
			string item11 = tuple3.Rest.Item2;
			long item12 = tuple3.Rest.Item3;
			string item13 = tuple3.Rest.Item4;
			bool item14 = tuple3.Rest.Item5;
			string item15 = tuple3.Rest.Item6;
			int item16 = tuple3.Rest.Item7;
			string item17 = tuple3.Rest.Rest.Item1;
			int item18 = tuple3.Rest.Rest.Item2;
			WeatherCategory item19 = tuple3.Rest.Rest.Item3;
			(IReadOnlyList<HudRow>? Rows, int Width, int Day, int Hour, int Minute, bool Use24, bool Night, WeatherCategory Category, string? Language, long Revision, string? Event, bool Forecast, string? ForecastName, int ForecastMinutes, string? ForecastWind, int ForecastPercent, WeatherCategory ForecastCategory) tuple4 = statusDrawn;
			IReadOnlyList<HudRow> item20 = tuple4.Rows;
			int item21 = tuple4.Width;
			int item22 = tuple4.Day;
			int item23 = tuple4.Hour;
			int item24 = tuple4.Minute;
			bool item25 = tuple4.Use24;
			bool item26 = tuple4.Night;
			WeatherCategory item27 = tuple4.Rest.Item1;
			string item28 = tuple4.Rest.Item2;
			long item29 = tuple4.Rest.Item3;
			string item30 = tuple4.Rest.Item4;
			bool item31 = tuple4.Rest.Item5;
			string item32 = tuple4.Rest.Item6;
			int item33 = tuple4.Rest.Item7;
			string item34 = tuple4.Rest.Rest.Item1;
			int item35 = tuple4.Rest.Rest.Item2;
			WeatherCategory item36 = tuple4.Rest.Rest.Item3;
			if (item3 == item20 && item4 == item21 && item5 == item22 && item6 == item23 && item7 == item24 && item8 == item25 && item9 == item26 && item10 == item27 && item11 == item28 && item12 == item29 && item13 == item30 && item14 == item31 && item15 == item32 && item16 == item33 && item17 == item34 && item18 == item35 && item19 == item36)
			{
				return;
			}
			statusDrawn = tuple2;
			bool flag3 = rows.Contains((HudRow)0);
			((Component)clockText).gameObject.SetActive(flag3);
			((Component)weatherText).gameObject.SetActive(flag3);
			((Component)clockIcon).gameObject.SetActive(false);
			((Component)weatherIcon).gameObject.SetActive(false);
			((Component)divider).gameObject.SetActive(false);
			if (!flag3)
			{
				return;
			}
			ClockParts val3 = HudText.Clock(((HudOptions)(ref options)).ShowDay, ((HudOptions)(ref options)).ShowTime, num, num2, flag);
			string text2 = HudText.Dot((((ClockParts)(ref val3)).Day.Length == 0) ? "" : CairnText.Format("hud_day", ((ClockParts)(ref val3)).Day), ((ClockParts)(ref val3)).Time);
			string text3 = (((HudOptions)(ref options)).ShowWeather ? CairnText.Text(text ?? CairnTextKeys.Weather(val2)) : "");
			string text4 = (((ForecastLine)(ref current)).Visible ? CairnForecast.Text(current) : "");
			bool flag4 = text2.Length > 0;
			float num4 = 7f;
			int num5 = HudLayout.Top(rows, (HudRow)0);
			float y = (float)num5 + 1f;
			clockText.text = text2;
			bool flag5 = flag4 && ((HudOptions)(ref options)).ShowTime;
			float num6 = (flag4 ? Mathf.Min(clockText.GetPreferredValues(text2).x, HudLayout.StatusRoom((float)panelWidth) - (flag5 ? 18f : 0f)) : 0f);
			float num7 = (flag5 ? 18f : 0f) + num6;
			weatherText.fontSize = 12f;
			float num8 = HudLayout.WeatherTextRoom((float)panelWidth, flag4 ? num7 : 0f);
			string text5 = ((text4.Length > 0 && text3.Length > 0) ? HudText.Dot(text3, text4) : "");
			bool flag6 = text5.Length > 0 && !HudLayout.FitText(weatherText.GetPreferredValues(text5).x, num8, 12f, 8f).Item2;
			string text6 = HudText.WithForecast(text3, text4, flag6);
			weatherText.text = text6;
			bool flag7 = text6.Length > 0;
			float num9 = 0f;
			if (flag7)
			{
				var (fontSize, flag8) = HudLayout.FitText(weatherText.GetPreferredValues(text6).x, num8, 12f, 8f);
				weatherText.fontSize = fontSize;
				weatherText.overflowMode = (TextOverflowModes)(flag8 ? 1 : 3);
				num9 = Mathf.Min(weatherText.GetPreferredValues(text6).x, num8);
			}
			float num10 = (flag7 ? (18f + num9) : 0f);
			var (num11, num12, num13) = HudLayout.StatusPlaces((float)panelWidth, flag4 ? num7 : 0f, num10, num4);
			if (flag4 && flag7)
			{
				((Component)divider).gameObject.SetActive(true);
				Place(((Graphic)divider).rectTransform, num12 - 0.5f, num5 + 3, 1f, 11f);
			}
			if (flag4)
			{
				float x = num11;
				if (flag5)
				{
					SetIcon(clockIcon, HudIcons.Clock(flag2), flag2 ? MoonTint : Gold);
					Place(((Graphic)clockIcon).rectTransform, num11, y, 15f, 15f);
					x = num11 + 15f + 3f;
				}
				clockText.alignment = (TextAlignmentOptions)513;
				Place(clockText.rectTransform, x, num5, num6 + 2f, 17f);
			}
			else
			{
				((Component)clockText).gameObject.SetActive(false);
			}
			int num14;
			(string, TempestGlyph)? obj;
			if (flag7)
			{
				if (text4.Length > 0)
				{
					num14 = ((text6 == text4) ? 1 : 0);
					if (num14 != 0)
					{
						obj = null;
						goto IL_0746;
					}
				}
				else
				{
					num14 = 0;
				}
				obj = tuple;
				goto IL_0746;
			}
			((Component)weatherText).gameObject.SetActive(false);
			return;
			IL_0746:
			(string, TempestGlyph)? tuple7 = obj;
			WeatherCategory val4 = ((num14 != 0) ? ((ForecastLine)(ref current)).Category : val2);
			Sprite val5 = (tuple7.HasValue ? EventGlyph(tuple7.Value.Item2) : null);
			if ((Object)(object)val5 != (Object)null)
			{
				SetGlyph(weatherIcon, val5);
			}
			else
			{
				HudIcon val6 = HudIcons.For(val4, flag2);
				SetIcon(weatherIcon, val6, ((int)val6 == 1) ? MoonTint : WeatherTint(val4));
			}
			Place(((Graphic)weatherIcon).rectTransform, num13, y, 15f, 15f);
			weatherText.alignment = (TextAlignmentOptions)513;
			Place(weatherText.rectTransform, num13 + 15f + 3f, num5, num9 + 2f, 17f);
		}

		private static Color WeatherTint(WeatherCategory category)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected I4, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_0060: 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)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			switch ((int)category)
			{
			case 0:
				return Gold;
			case 3:
			case 4:
				return new Color(0.62f, 0.78f, 1f, 1f);
			case 5:
			case 6:
				return new Color(0.88f, 0.95f, 1f, 1f);
			case 7:
				return new Color(0.85f, 0.62f, 0.5f, 1f);
			case 8:
				return new Color(1f, 0.45f, 0.35f, 1f);
			default:
				return new Color(0.86f, 0.88f, 0.92f, 1f);
			}
		}

		private static void DrawStrip(IReadOnlyList<HudRow> rows, HudOptions options, float heading, int panelWidth)
		{
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			(IReadOnlyList<HudRow>, int, bool) tuple = (rows, panelWidth, PlateReady((HudRow)1));
			var (readOnlyList, num, flag) = tuple;
			var (readOnlyList2, num2, flag2) = stripDrawn;
			if (readOnlyList == readOnlyList2 && num == num2 && flag == flag2)
			{
				return;
			}
			stripDrawn = tuple;
			int num3 = HudLayout.PlankHeight(rows);
			SetPlate((HudRow)1, num3 > 0, 0f, 0f, panelWidth, num3, KitHudArt.CompassPlank, (float)num3 * 4f);
			bool flag3 = PlateReady((HudRow)1) && num3 >= 34;
			for (int i = 0; i < capRivets.Length; i++)
			{
				if (flag3)
				{
					float num4 = ((i == 0) ? 11f : ((float)panelWidth - 11f)) - 3.25f;
					capRivets[i] = KitHudArt.Plate(panel.Content, "Cairn_CapRivet" + i, KitHudArt.IronRivet, 32f, new Vector2(num4, (0f - ((float)num3 - 6.5f)) * 0.5f), new Vector2(6.5f, 6.5f));
				}
				if ((Object)(object)capRivets[i] != (Object)null)
				{
					((Component)capRivets[i]).gameObject.SetActive(flag3);
				}
			}
		}

		private static void DrawHeading(IReadOnlyList<HudRow> rows, float heading, int panelWidth, string language, long revision)
		{
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			(IReadOnlyList<HudRow>, int, int, string, string, long, bool) tuple = (rows, panelWidth, Compass.Degrees(heading), Compass.Point(heading), language, revision, PlateReady((HudRow)2));
			var (readOnlyList, num, num2, text, text2, num3, flag) = tuple;
			var (readOnlyList2, num4, num5, text3, text4, num6, flag2) = headingDrawn;
			if (readOnlyList != readOnlyList2 || num != num4 || num2 != num5 || !(text == text3) || !(text2 == text4) || num3 != num6 || flag != flag2)
			{
				headingDrawn = tuple;
				bool flag3 = rows.Contains((HudRow)2);
				int num7 = (flag3 ? HudLayout.Top(rows, (HudRow)2) : 0) + 12 - 14;
				SetPlate((HudRow)2, flag3, ((float)panelWidth - 64f) * 0.5f, num7, 64f, 14f, KitHudArt.CompassInset, 56f);
				TMP_Text val = labels[(HudRow)2];
				((Component)val).gameObject.SetActive(flag3);
				if (flag3)
				{
					HeadingParts val2 = HudText.Heading(heading);
					val.text = CairnText.Format("hud_heading", ((HeadingParts)(ref val2)).Degrees, CairnText.Text(((HeadingParts)(ref val2)).PointKey));
					Place(val.rectTransform, ((float)panelWidth - 64f) * 0.5f + 6f, (float)num7 + 1f, 52f, 13f);
				}
			}
		}

		private static void DrawExtras(IReadOnlyList<HudRow> rows, int panelWidth, string language, long revision)
		{
			//IL_000e: 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)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: 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)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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)
			//IL_00ed: 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_0107: Invalid comparison between Unknown and I4
			//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0622: Unknown result type (might be due to invalid IL or missing references)
			//IL_0627: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_056d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_061a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			for (int i = 0; i < extraRows.Count; i++)
			{
				if (PlateReady(extraRows[i]))
				{
					num |= 1 << i;
				}
			}
			(IReadOnlyList<HudRow>, int, int) tuple = (rows, panelWidth, num);
			var (readOnlyList, num2, num3) = tuple;
			var (readOnlyList2, num4, num5) = extrasDrawn;
			if (readOnlyList != readOnlyList2 || num2 != num4 || num3 != num5)
			{
				extrasDrawn = tuple;
				foreach (HudRow extraRow in extraRows)
				{
					bool flag = rows.Contains(extraRow);
					int num6 = (flag ? HudLayout.Top(rows, extraRow) : 0);
					SetPlate(extraRow, flag, 0f, num6, panelWidth, 14f, KitHudArt.HeadingPlate, 46f);
					((Component)labels[extraRow]).gameObject.SetActive(flag);
					if (flag && (int)extraRow != 4)
					{
						Place(labels[extraRow].rectTransform, 13.200001f, num6, (float)panelWidth - 26.400002f, 14f);
					}
				}
			}
			RadiusResult? last = CairnRadius.Last;
			(bool, float, float, float, float, float, float, float, string, long) valueTuple;
			if (!last.HasValue)
			{
				valueTuple = (false, 0f, 0f, 0f, 0f, 0f, 0f, 0f, language, revision);
			}
			else
			{
				RadiusResult value = last.Value;
				float radius = ((RadiusResult)(ref value)).Radius;
				value = last.Value;
				float item = ((RadiusResult)(ref value)).Base;
				value = last.Value;
				float multiplier = ((RadiusResult)(ref value)).Multiplier;
				value = last.Value;
				float lightTerm = ((RadiusResult)(ref value)).LightTerm;
				value = last.Value;
				float weatherTerm = ((RadiusResult)(ref value)).WeatherTerm;
				value = last.Value;
				float altitudeTerm = ((RadiusResult)(ref value)).AltitudeTerm;
				value = last.Value;
				valueTuple = (true, radius, item, multiplier, lightTerm, weatherTerm, altitudeTerm, ((RadiusResult)(ref value)).LocationTerm, language, revision);
			}
			(bool, float, float, float, float, float, float, float, string, long) tuple4 = valueTuple;
			bool hasValue;
			if (rows.Contains((HudRow)5))
			{
				(bool, float, float, float, float, float, float, float, string, long)? tuple5 = radiusDrawn;
				(bool, float, float, float, float, float, float, float, string, long) tuple6 = tuple4;
				hasValue = tuple5.HasValue;
				if (!hasValue)
				{
					goto IL_0322;
				}
				if (hasValue)
				{
					(bool, float, float, float, float, float, float, float, string, long) valueOrDefault = tuple5.GetValueOrDefault();
					if (valueOrDefault.Item1 != tuple6.Item1 || valueOrDefault.Item2 != tuple6.Item2 || valueOrDefault.Item3 != tuple6.Item3 || valueOrDefault.Item4 != tuple6.Item4 || valueOrDefault.Item5 != tuple6.Item5 || valueOrDefault.Item6 != tuple6.Item6 || valueOrDefault.Item7 != tuple6.Item7 || valueOrDefault.Rest.Item1 != tuple6.Rest.Item1 || valueOrDefault.Rest.Item2 != tuple6.Rest.Item2 || valueOrDefault.Rest.Item3 != tuple6.Rest.Item3)
					{
						goto IL_0322;
					}
				}
			}
			goto IL_036c;
			IL_0322:
			radiusDrawn = tuple4;
			labels[(HudRow)5].text = (last.HasValue ? CairnText.Format("radius_line", HudText.RadiusArgument(last.Value)) : "");
			goto IL_036c;
			IL_060d:
			(TempestLineKind, string, string, string, string, long, IReadOnlyList<HudRow>, int) tuple7;
			tempestDrawn = tuple7;
			TempestLine line;
			DrawTempest(rows, line, panelWidth);
			goto IL_0622;
			IL_04ca:
			line = CairnTempest.Line;
			tuple7 = (((TempestLine)(ref line)).Kind, ((TempestLine)(ref line)).TextKey, ((TempestLine)(ref line)).EventKey, ((TempestLine)(ref line)).Countdown, language, revision, rows, panelWidth);
			if (!rows.Contains((HudRow)4))
			{
				if (((Component)eventIcon).gameObject.activeSelf)
				{
					((Component)eventIcon).gameObject.SetActive(false);
				}
			}
			else
			{
				(TempestLineKind, string, string, string, string, long, IReadOnlyList<HudRow>, int)? tuple8 = tempestDrawn;
				(TempestLineKind, string, string, string, string, long, IReadOnlyList<HudRow>, int) tuple9 = tuple7;
				hasValue = tuple8.HasValue;
				if (!hasValue)
				{
					goto IL_060d;
				}
				if (hasValue)
				{
					(TempestLineKind, string, string, string, string, long, IReadOnlyList<HudRow>, int) valueOrDefault2 = tuple8.GetValueOrDefault();
					(TempestLineKind, string, string, string, string, long, IReadOnlyList<HudRow>, int) tuple10 = tuple9;
					if (valueOrDefault2.Item1 != tuple10.Item1 || valueOrDefault2.Item2 != tuple10.Item2 || valueOrDefault2.Item3 != tuple10.Item3 || valueOrDefault2.Item4 != tuple10.Item4 || valueOrDefault2.Item5 != tuple10.Item5 || valueOrDefault2.Item6 != tuple10.Item6 || valueOrDefault2.Item7 != tuple10.Item7 || valueOrDefault2.Rest.Item1 != tuple10.Rest.Item1)
					{
						goto IL_060d;
					}
				}
			}
			goto IL_0622;
			IL_0622:
			SleepDisplay line2 = CairnSleep.Line;
			(bool, string, string, string, string, string, long) tuple11 = (((SleepDisplay)(ref line2)).Visible, ((SleepDisplay)(ref line2)).Sleeping, ((SleepDisplay)(ref line2)).Players, ((SleepDisplay)(ref line2)).SkipPercent, ((SleepDisplay)(ref line2)).BoostPercent, language, revision);
			if (!rows.Contains((HudRow)3))
			{
				return;
			}
			(bool, string, string, string, string, string, long)? tuple12 = sleepDrawn;
			(bool, string, string, string, string, string, long) tuple13 = tuple11;
			hasValue = tuple12.HasValue;
			if (hasValue)
			{
				if (!hasValue)
				{
					return;
				}
				(bool, string, string, string, string, string, long) valueOrDefault3 = tuple12.GetValueOrDefault();
				if (valueOrDefault3.Item1 == tuple13.Item1 && !(valueOrDefault3.Item2 != tuple13.Item2) && !(valueOrDefault3.Item3 != tuple13.Item3) && !(valueOrDefault3.Item4 != tuple13.Item4) && !(valueOrDefault3.Item5 != tuple13.Item5) && !(valueOrDefault3.Item6 != tuple13.Item6) && valueOrDefault3.Item7 == tuple13.Item7)
				{
					return;
				}
			}
			sleepDrawn = tuple11;
			labels[(HudRow)3].text = CairnSleep.Text;
			return;
			IL_036c:
			if (rows.Contains((HudRow)6))
			{
				(bool, float, float, float, float, float, float, float, string, long)? tuple5 = inputsDrawn;
				(bool, float, float, float, float, float, float, float, string, long) tuple6 = tuple4;
				hasValue = tuple5.HasValue;
				if (!hasValue)
				{
					goto IL_047f;
				}
				if (hasValue)
				{
					(bool, float, float, float, float, float, float, float, string, long) valueOrDefault = tuple5.GetValueOrDefault();
					if (valueOrDefault.Item1 != tuple6.Item1 || valueOrDefault.Item2 != tuple6.Item2 || valueOrDefault.Item3 != tuple6.Item3 || valueOrDefault.Item4 != tuple6.Item4 || valueOrDefault.Item5 != tuple6.Item5 || valueOrDefault.Item6 != tuple6.Item6 || valueOrDefault.Item7 != tuple6.Item7 || valueOrDefault.Rest.Item1 != tuple6.Rest.Item1 || valueOrDefault.Rest.Item2 != tuple6.Rest.Item2 || valueOrDefault.Rest.Item3 != tuple6.Rest.Item3)
					{
						goto IL_047f;
					}
				}
			}
			goto IL_04ca;
			IL_047f:
			inputsDrawn = tuple4;
			labels[(HudRow)6].text = (last.HasValue ? CairnText.Format("radius_inputs", HudText.RadiusInputArguments(last.Value).Cast<object>().ToArray()) : "");
			goto IL_04ca;
		}

		private static void DrawTempest(IReadOnlyList<HudRow> rows, TempestLine line, int panelWidth)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_0049: 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)
			TMP_Text val = labels[(HudRow)4];
			string text = (val.text = CairnTempest.Text(line));
			((Graphic)val).color = KitAppearance.Color((KitColorRole)6);
			int num = HudLayout.Top(rows, (HudRow)4);
			float x = 13.200001f;
			float num2 = (float)panelWidth - 26.400002f;
			Sprite val2 = (((int)((TempestLine)(ref line)).Kind == 0) ? null : EventGlyph(((TempestLine)(ref line)).Glyph));
			if ((Object)(object)val2 == (Object)null)
			{
				((Component)eventIcon).gameObject.SetActive(false);
				val.alignment = (TextAlignmentOptions)514;
				Place(val.rectTransform, x, num, num2, 14f);
				return;
			}
			float num3 = Mathf.Min(val.GetPreferredValues(text).x, num2 - 11f - 3f);
			float num4 = ((float)panelWidth - (14f + num3)) * 0.5f;
			SetGlyph(eventIcon, val2);
			Place(((Graphic)eventIcon).rectTransform, num4, (float)num + 1.5f, 11f, 11f);
			val.alignment = (TextAlignmentOptions)513;
			Place(val.rectTransform, num4 + 11f + 3f, num, num3 + 2f, 14f);
		}

		private static Sprite? EventGlyph(TempestGlyph glyph)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected I4, but got Unknown
			return (Sprite?)((glyph - 1) switch
			{
				0 => KitGlyphSprites.Of((KitGlyph)14), 
				2 => KitGlyphSprites.Of((KitGlyph)21), 
				3 => KitGlyphSprites.Of((KitGlyph)10), 
				_ => KitGlyphSprites.Of((KitGlyph)15), 
			});
		}

		private static void SetGlyph(Image image, Sprite glyph)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			image.sprite = glyph;
			((Graphic)image).color = KitAppearance.Color((KitColorRole)6);
			((Component)image).gameObject.SetActive(true);
		}

		private unsafe static void SetPlate(HudRow row, bool on, float x, float y, float width, float height, Sprite? sprite, float sourceHeight)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: 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_0061: 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)
			if (!plates.TryGetValue(row, out Image value) || (Object)(object)value == (Object)null)
			{
				if (!on || (Object)(object)sprite == (Object)null || panel == null)
				{
					return;
				}
				value = KitHudArt.Plate(panel.Content, "Cairn_Plate_" + ((object)(*(HudRow*)(&row))/*cast due to .constrained prefix*/).ToString(), sprite, sourceHeight, new Vector2(x, 0f - y), new Vector2(width, height));
				if ((Object)(object)value == (Object)null)
				{
					return;
				}
				plates[row] = value;
				((Component)value).transform.SetAsFirstSibling();
				if (plates.TryGetValue((HudRow)1, out Image value2) && (Object)(object)value2 != (Object)null)
				{
					((Component)value2).transform.SetAsFirstSibling();
				}
			}
			((Component)value).gameObject.SetActive(on);
			if (on)
			{
				KitHudArt.Plate(panel.Content, ((Object)((Component)value).gameObject).name, sprite, sourceHeight, new Vector2(x, 0f - y), new Vector2(width, height));
				((Graphic)value).raycastTarget = false;
			}
		}

		internal static void ToggleFromMenu()
		{
			if (!CairnModules.StepAside.SteppedAside((CairnModule)2))
			{
				toggledOff = !toggledOff;
			}
		}

		private static bool TogglePressed(CairnConfig settings)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			string text = settings.Get<string>(Hud.ToggleKey);
			if (!string.Equals(text, toggleKeyText, StringComparison.Ordinal))
			{
				toggleKeyText = text;
				toggleKeyValid = Enum.TryParse<KeyCode>(text, ignoreCase: true, out KeyCode result);
				toggleKey = (KeyboardShortcut)(toggleKeyValid ? new KeyboardShortcut(result, Array.Empty<KeyCode>()) : KeyboardShortcut.Empty);
			}
			if (toggleKeyValid && Input.GetKeyDown(((KeyboardShortcut)(ref toggleKey)).MainKey) && MeadworksInput.Pressed(toggleKey, (InputContext)0))
			{
				return true;
			}
			return PadChordPressed(settings.Get<string>(Hud.GamepadToggle));
		}

		internal static bool PadChordPressed(string value)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (!chords.TryGetValue(value, out PadButton[] value2))
			{
				List<PadButton> list = new List<PadButton>();
				string[] array = value.Split(new char[1] { '+' }, StringSplitOptions.RemoveEmptyEntries);
				PadButton item = default(PadButton);
				for (int i = 0; i < array.Length; i++)
				{
					if (!GamepadMap.TryParse(array[i], ref item))
					{
						list = null;
						break;
					}
					list.Add(item);
				}
				value2 = list?.ToArray();
				chords[value] = value2;
			}
			if (value2 == null)
			{
				return false;
			}
			if (!MeadworksInput.GamepadActive || value2.Length == 0)
			{
				return false;
			}
			PadButton[] array2 = value2;
			for (int i = 0; i < array2.Length; i++)
			{
				if (!MeadworksInput.PadHeld(array2[i]))
				{
					return false;
				}
			}
			bool flag = false;
			array2 = value2;
			for (int i = 0; i < array2.Length; i++)
			{
				if (MeadworksInput.PadDown(array2[i]))
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				return false;
			}
			array2 = value2;
			for (int i = 0; i < array2.Length; i++)
			{
				MeadworksInput.PadConsume(array2[i]);
			}
			return true;
		}

		private static void Build(Transform root)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: 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)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Invalid comparison between Unknown and I4
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Invalid comparison between Unknown and I4
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Invalid comparison between Unknown and I4
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Invalid comparison between Unknown and I4
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: 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)
			panel = KitHudPanel.Create(root, "Cairn_Hud", new Vector2(240f, 51f), Vector2.zero, "com.meadworks.cairn", "Cairn_Hud");
			if (panel == null)
			{
				return;
			}
			owner = root;
			clockText = Label("Clock", 12, Cream);
			weatherText = Label("Weather", 12, Cream);
			clockIcon = Glyph("ClockIcon");
			weatherIcon = Glyph("WeatherIcon");
			eventIcon = Glyph("TempestIcon");
			KitAppearance.Changed -= Redraw;
			KitAppearance.Changed += Redraw;
			divider = Bar("Divider", Bronze);
			pointer = Bar("Pointer", Gold);
			foreach (HudRow value2 in Enum.GetValues(typeof(HudRow)))
			{
				if ((int)value2 != 0 && (int)value2 != 1)
				{
					TMP_Text value = Label(((object)value2/*cast due to .constrained prefix*/).ToString(), ((int)value2 == 6) ? 10 : (((int)value2 == 2) ? 9 : 11), ((int)value2 == 2) ? Cream : KitAppearance.Color((KitColorRole)6));
					labels.Add(value2, value);
					if (HudLayout.IsExtra(value2))
					{
						extraRows.Add(value2);
					}
				}
			}
			Redraw();
			labels[(HudRow)2].overflowMode = (TextOverflowModes)0;
		}

		private static TMP_Text Label(string name, int size, Color colour)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			TMP_Text obj = KitCanvas.Text((Transform)(object)panel.Content, "Cairn_" + name, "", (float)size, colour, (TextAlignmentOptions)514, false);
			((Graphic)obj).raycastTarget = false;
			obj.textWrappingMode = (TextWrappingModes)0;
			obj.overflowMode = (TextOverflowModes)3;
			return obj;
		}

		private static Image Glyph(string name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			Image obj = Bar(name, Color.white);
			obj.preserveAspect = true;
			return obj;
		}

		private static Image Bar(string name, Color colour)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Cairn_" + name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent((Transform)(object)panel.Content, false);
			Image component = val.GetComponent<Image>();
			((Graphic)component).raycastTarget = false;
			((Graphic)component).color = colour;
			val.SetActive(false);
			return component;
		}

		private unsafe static void SetIcon(Image image, HudIcon icon, Color tint)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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_0089: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_00d9: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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)
			if (!icons.TryGetValue(icon, out Sprite value) || (Object)(object)value == (Object)null)
			{
				byte[] array = HudIcons.Mask(icon, 16);
				Color32[] array2 = (Color32[])(object)new Color32[array.Length];
				for (int i = 0; i < 16; i++)
				{
					for (int j = 0; j < 16; j++)
					{
						array2[(15 - i) * 16 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, array[i * 16 + j]);
					}
				}
				Texture2D val = new Texture2D(16, 16, (TextureFormat)4, false)
				{
					filterMode = (FilterMode)1,
					wrapMode = (TextureWrapMode)1,
					name = "Cairn_Icon_" + ((object)(*(HudIcon*)(&icon))/*cast due to .constrained prefix*/).ToString()
				};
				val.SetPixels32(array2);
				val.Apply(false, true);
				value = Sprite.Create(val, new Rect(0f, 0f, 16f, 16f), new Vector2(0.5f, 0.5f), 100f);
				((Object)value).name = ((Object)val).name;
				icons[icon] = value;
			}
			image.sprite = value;
			((Graphic)image).color = tint;
			((Component)image).gameObject.SetActive(true);
		}

		private static void DrawCompass(bool show, IReadOnlyList<HudRow> rows, float heading, int width, int panelWidth, Player player, CairnConfig settings, string language, long revision)
		{
			//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_0104: 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_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0488: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Invalid comparison between Unknown and I4
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Invalid comparison between Unknown and I4
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_0507: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_08bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0538: Unknown result type (might be due to invalid IL or missing references)
			//IL_053e: Invalid comparison between Unknown and I4
			//IL_08ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_062b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0630: Unknown result type (might be due to invalid IL or missing references)
			//IL_0551: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0719: Unknown result type (might be due to invalid IL or missing references)
			//IL_071e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0674: Unknown result type (might be due to invalid IL or missing references)
			//IL_0679: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0749: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_07cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_080b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0810: Unknown result type (might be due to invalid IL or missing references)
			//IL_0822: Unknown result type (might be due to invalid IL or missing references)
			//IL_0830: Unknown result type (might be due to invalid IL or missing references)
			//IL_0835: Unknown result type (might be due to invalid IL or missing references)
			//IL_0847: Unknown result type (might be due to invalid IL or missing references)
			//IL_09d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_09bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_09d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_09f3: Unknown result type (might be due to invalid IL or missing references)
			bool flag = show && settings.Get<bool>(Hud.ShowMarkers) && (Object)(object)Minimap.instance != (Object)null;
			if (flag && Time.unscaledTime >= nextMarkers)
			{
				nextMarkers = Time.unscaledTime + 0.25f;
				MarkerChoices choices = CairnMarkers.Load();
				List<PinData> a = Minimap.instance.m_pins.Where((PinData p) => p != null && (choices.Contains("type:" + ((object)Unsafe.As<PinType, PinType>(ref p.m_type)/*cast due to .constrained prefix*/).ToString()) || choices.Contains(MarkerChoices.PinKey(p.m_pos.x, p.m_pos.z, ((object)Unsafe.As<PinType, PinType>(ref p.m_type)/*cast due to .constrained prefix*/).ToString())))).ToList();
				if (!SameList(a, selected))
				{
					selected = a;
				}
			}
			Vector3 position = ((Component)player).transform.position;
			bool flag2 = flag && selected.Count > 0;
			(bool, IReadOnlyList<HudRow>, int, int, float, string, long, bool, List<PinData>, float, float, int, float) tuple = (show ? (true, rows, panelWidth, settings.Get<int>(Hud.StripDegrees), heading, language, revision, flag, flag ? selected : null, flag2 ? position.x : 0f, flag2 ? position.z : 0f, flag ? settings.Get<int>(Hud.MaxMarkers) : 0, flag ? settings.Get<float>(Hud.MaxDistance) : 0f) : (false, rows, panelWidth, 0, 0f, null, 0L, false, null, 0f, 0f, 0, 0f));
			bool flag3 = !flag || SamePins(selected);
			(bool, IReadOnlyList<HudRow>, int, int, float, string, long, bool, List<PinData>, float, float, int, float) tuple2 = tuple;
			bool item = tuple2.Item1;
			IReadOnlyList<HudRow> item2 = tuple2.Item2;
			int item3 = tuple2.Item3;
			int item4 = tuple2.Item4;
			float item5 = tuple2.Item5;
			string item6 = tuple2.Item6;
			long item7 = tuple2.Item7;
			bool item8 = tuple2.Rest.Item1;
			List<PinData> item9 = tuple2.Rest.Item2;
			float item10 = tuple2.Rest.Item3;
			float item11 = tuple2.Rest.Item4;
			int item12 = tuple2.Rest.Item5;
			float item13 = tuple2.Rest.Item6;
			(bool Show, IReadOnlyList<HudRow>? Rows, int Width, int Degrees, float Heading, string? Language, long Revision, bool Markers, List<PinData>? Selected, float X, float Z, int Max, float MaxDistance) tuple3 = compassDrawn;
			bool item14 = tuple3.Show;
			IReadOnlyList<HudRow> item15 = tuple3.Rows;
			int item16 = tuple3.Width;
			int item17 = tuple3.Degrees;
			float item18 = tuple3.Heading;
			string item19 = tuple3.Language;
			long item20 = tuple3.Revision;
			bool item21 = tuple3.Rest.Item1;
			List<PinData> item22 = tuple3.Rest.Item2;
			float item23 = tuple3.Rest.Item3;
			float item24 = tuple3.Rest.Item4;
			int item25 = tuple3.Rest.Item5;
			float item26 = tuple3.Rest.Item6;
			if (item == item14 && item2 == item15 && item3 == item16 && item4 == item17 && item5 == item18 && item6 == item19 && item7 == item20 && item8 == item21 && item9 == item22 && item10 == item23 && item11 == item24 && item12 == item25 && item13 == item26 && flag3)
			{
				return;
			}
			compassDrawn = tuple;
			if (!flag3)
			{
				drawnPins.Clear();
				foreach (PinData item27 in selected)
				{
					drawnPins.Add((item27.m_pos.x, item27.m_pos.z, item27.m_icon, (Object)(object)item27.m_icon != (Object)null, item27.m_type));
				}
			}
			foreach (TMP_Text tick in ticks)
			{
				((Component)tick).gameObject.SetActive(false);
			}
			foreach (Image mark in marks)
			{
				((Component)mark).gameObject.SetActive(false);
			}
			foreach (var marker in markers)
			{
				((Component)marker.Icon).gameObject.SetActive(false);
				((Component)marker.Distance).gameObject.SetActive(false);
			}
			((Component)pointer).gameObject.SetActive(show);
			if (!show)
			{
				return;
			}
			int num = HudLayout.Top(rows, (HudRow)1);
			float num2 = (float)panelWidth * 0.5f;
			int num3 = settings.Get<int>(Hud.StripDegrees);
			Place(((Graphic)pointer).rectTransform, num2 - 1f, num + 1, 2f, 6f);
			int num4 = 0;
			foreach (StripMark item28 in Compass.Marks(heading, num3, width))
			{
				StripMark current3 = item28;
				if (num4 == marks.Count)
				{
					marks.Add(Bar("Mark" + num4, Cream));
				}
				Image obj = marks[num4++];
				float height = (((int)((StripMark)(ref current3)).Kind == 2) ? 6f : (((int)((StripMark)(ref current3)).Kind == 1) ? 4f : 2f));
				Color cream = Cream;
				cream.a = (((int)((StripMark)(ref current3)).Kind == 0) ? 0.55f : 0.9f) * Compass.EdgeFade(((StripMark)(ref current3)).Offset, width);
				if (((StripMark)(ref current3)).Degrees == 0 && (int)((StripMark)(ref current3)).Kind == 2)
				{
					((Color)(ref cream))..ctor(0.92f, 0.25f, 0.2f, cream.a);
				}
				((Graphic)obj).color = cream;
				((Component)obj).gameObject.SetActive(true);
				Place(((Graphic)obj).rectTransform, num2 + ((StripMark)(ref current3)).Offset - 0.5f, (float)num + 3f, 1f, height);
			}
			pinOffsets.Clear();
			bool flag4 = false;
			if (flag)
			{
				IEnumerable<MarkerPin> enumerable = ((IEnumerable<PinData>)selected).Select((Func<PinData, int, MarkerPin>)((PinData p, int index) => new MarkerPin(index.ToString(), p.m_pos.x, p.m_pos.z)));
				int num5 = 0;
				foreach (MarkerPin item29 in Compass.Nearest(enumerable, position.x, position.z, settings.Get<int>(Hud.MaxMarkers), settings.Get<float>(Hud.MaxDistance)))
				{
					MarkerPin current4 = item29;
					if (num5 == markers.Count)
					{
						GameObject val = new GameObject("Cairn_CompassPin" + num5, new Type[2]
						{
							typeof(RectTransform),
							typeof(Image)
						});
						val.transform.SetParent((Transform)(object)panel.Content, false);
						Image component = val.GetComponent<Image>();
						((Graphic)component).raycastTarget = false;
						markers.Add((component, Label("CompassDistance" + num5, 8, Cream)));
					}
					(Image, TMP_Text) tuple4 = markers[num5++];
					PinData val2 = selected[int.Parse(((MarkerPin)(ref current4)).Id)];
					StripPosition val3 = Compass.OnStrip(Compass.Bearing(position.x, position.z, ((MarkerPin)(ref current4)).X, ((MarkerPin)(ref current4)).Z), heading, num3, width);
					float num6 = num2 + ((StripPosition)(ref val3)).Offset;
					tuple4.Item1.sprite = (((Object)(object)val2.m_icon != (Object)null) ? val2.m_icon : Minimap.instance.GetSprite(val2.m_type));
					((Component)tuple4.Item1).gameObject.SetActive((Object)(object)tuple4.Item1.sprite != (Object)null);
					Place(((Graphic)tuple4.Item1).rectTransform, num6 - 5f, num + 3, 10f, 10f);
					((Component)tuple4.Item2).gameObject.SetActive(true);
					tuple4.Item2.text = Compass.DistanceText(Compass.Distance(position.x, position.z, ((MarkerPin)(ref current4)).X, ((MarkerPin)(ref current4)).Z));
					float a2 = Compass.MarkerAlpha(((StripPosition)(ref val3)).Parked, ((StripPosition)(ref val3)).Offset, width);
					Color color = ((Graphic)tuple4.Item1).color;
					color.a = a2;
					((Graphic)tuple4.Item1).color = color;
					Color color2 = ((Graphic)tuple4.Item2).color;
					color2.a = a2;
					((Graphic)tuple4.Item2).color = color2;
					Place(tuple4.Item2.rectTransform, num6 - 24f, num + 13, 48f, 9f);
					pinOffsets.Add(((StripPosition)(ref val3)).Offset);
					flag4 = true;
				}
			}
			num4 = 0;
			foreach (StripTick item30 in Compass.Ticks(heading, num3, width))
			{
				StripTick current5 = item30;
				if (num4 == ticks.Count)
				{
					ticks.Add(Label("CompassTick" + num4, 9, Cream));
					ticks[num4].overflowMode = (TextOverflowModes)0;
				}
				TMP_Text val4 = ticks[num4++];
				bool flag5 = false;
				if (flag4)
				{
					foreach (float pinOffset in pinOffsets)
					{
						if (Math.Abs(pinOffset - ((StripTick)(ref current5)).Offset) < 22f)
						{
							flag5 = true;
							break;
						}
					}
				}
				((Component)val4).gameObject.SetActive(!flag5);
				if (!flag5)
				{
					val4.text = ((((StripTick)(ref current5)).Degrees % 45 == 0) ? CairnText.Text(CairnTextKeys.CompassPoint(((StripTick)(ref current5)).Label)) : ((StripTick)(ref current5)).Label);
					Color color3 = (Color)(((StripTick)(ref current5)).North ? new Color(0.95f, 0.27f, 0.22f) : Cream);
					color3.a *= Compass.EdgeFade(((StripTick)(ref current5)).Offset, width);
					((Graphic)val4).color = color3;
					val4.fontSize = (((StripTick)(ref current5)).Major ? 10 : 8);
					Place(val4.rectTransform, num2 + ((StripTick)(ref current5)).Offset - 14f, num + 8, 28f, 14f);
				}
			}
		}

		private static bool SameList(List<PinData> a, List<PinData> b)
		{
			if (a.Count != b.Count)
			{
				return false;
			}
			for (int i = 0; i < a.Count; i++)
			{
				if (a[i] != b[i])
				{
					return false;
				}
			}
			return true;
		}

		private static bool SamePins(List<PinData> pins)
		{
			//IL_0075: 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)
			if (pins.Count != drawnPins.Count)
			{
				return false;
			}
			for (int i = 0; i < pins.Count; i++)
			{
				PinData val = pins[i];
				(float, float, Sprite, bool, PinType) tuple = drawnPins[i];
				if (val.m_pos.x != tuple.Item1 || val.m_pos.z != tuple.Item2 || val.m_icon != tuple.Item3 || (Object)(object)val.m_icon != (Object)null != tuple.Item4 || val.m_type != tuple.Item5)
				{
					return false;
				}
			}
			return true;
		}

		private static void Place(RectTransform rect, float x, float y, float width, float height)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 1f);
			rect.pivot = val;
			Vector2 anchorMin = (rect.anchorMax = val);
			rect.anchorMin = anchorMin;
			rect.anchoredPosition = new Vector2(x, 0f - y);
			rect.sizeDelta = new Vector2(width, height);
		}

		private static void Hide()
		{
			HideHud();
			CairnMinimapEffects.Hide();
		}

		private static void HideHud()
		{
			TempestNotice.HudRowDrawn = false;
			KitHudPanel? obj = panel;
			if (obj != null)
			{
				obj.Update(false, false, 1f, 0f);
			}
		}

		private static void DisposePanel()
		{
			TempestNotice.HudRowDrawn = false;
			if (panel != null)
			{
				KitAppearance.Changed -= Redraw;
			}
			KitHudPanel? obj = panel;
			if (obj != null)
			{
				obj.Dispose();
			}
			panel = null;
			owner = null;
			labels.Clear();
			plates.Clear();
			Array.Clear(capRivets, 0, capRivets.Length);
			ticks.Clear();
			marks.Clear();
			markers.Clear();
			placement = null;
			extraRows.Clear();
			Redraw();
			clockText = (weatherText = null);
			clockIcon = (weatherIcon = (eventIcon = (divider = (pointer = null))));
		}

		public static void Reset()
		{
			CairnMinimapEffects.Dispose();
			DisposePanel();
			selected.Clear();
			character = null;
			world = 0L;
			toggledOff = false;
			ownsSleep = (showingSleep = false);
			nextMarkers = 0f;
			foreach (Sprite value in icons.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)value.texture);
					Object.Destroy((Object)(object)value);
				}
			}
			icons.Clear();
		}
	}
	public static class CairnMarkers
	{
		public static MarkerChoices Load()
		{
			Player localPlayer = Player.m_localPlayer;
			ZNet instance = ZNet.instance;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null)
			{
				return MarkerChoices.Default;
			}
			if (!localPlayer.m_customData.TryGetValue(MarkerChoices.DataKey(instance.GetWorldUID()), out var value))
			{
				return MarkerChoices.Default;
			}
			return MarkerChoices.Parse(value);
		}

		public static void Save(MarkerChoices choices)
		{
			Player localPlayer = Player.m_localPlayer;
			ZNet instance = ZNet.instance;
			if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)instance == (Object)null) && choices != null)
			{
				localPlayer.m_customData[MarkerChoices.DataKey(instance.GetWorldUID())] = choices.Serialize();
			}
		}
	}
	public sealed class CairnMarkerMap : IDisposable
	{
		private static readonly Color Dimmed = new Color(1f, 1f, 1f, 0.7f);

		private readonly KitMapView view;

		private Texture2D? picture;

		private Sprite? arrow;

		private bool pictureFailed;

		private bool framed;

		private MarkerMapPlan? plan;

		public Action<MarkerChoices>? OnChanged { get; set; }

		public Action<string>? OnShownByType { get; set; }

		private CairnMarkerMap(KitMapView view)
		{
			this.view = view;
			view.OnSelect = Clicked;
		}

		public static CairnMarkerMap? Create(RectTransform parent, Vector2 at, Vector2 size)
		{
			//IL_0015: 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)
			if ((Object)(object)Minimap.instance == (Object)null)
			{
				return null;
			}
			KitMapView val = KitMapView.Create(parent, "CairnMa