Decompiled source of YoureCold v0.2.7

YoureCold.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace YoureCold;

[BepInPlugin("com.marccunningham.yourecold", "You're Cold", "0.3.0")]
[BepInProcess("valheim.exe")]
public sealed class YoureColdPlugin : BaseUnityPlugin
{
	private enum HudResizeHandle
	{
		None,
		TopLeft,
		TopRight,
		BottomLeft,
		BottomRight
	}

	public const string PluginGuid = "com.marccunningham.yourecold";

	public const string PluginName = "You're Cold";

	public const string PluginVersion = "0.3.0";

	private const float MinimumTemperature = 0f;

	private const float MaximumTemperature = 100f;

	private const float MinimumTickInterval = 0.1f;

	private const float MaximumElapsedMultiplier = 3f;

	private const float HudReferenceWidth = 2048f;

	private const float HudReferenceHeight = 1152f;

	private const float CompactHudReferenceLeft = 247f;

	private const float CompactHudReferenceBottom = 118f;

	private const float CompactHudReferenceWidth = 221f;

	private const float CompactHudReferenceHeight = 58f;

	private ConfigEntry<bool> modEnabled;

	private ConfigEntry<KeyCode> diagnosticKey;

	private ConfigEntry<KeyCode> sessionToggleKey;

	private ConfigEntry<float> tickInterval;

	private ConfigEntry<float> startingTemperature;

	private ConfigEntry<string> difficultyPreset;

	private ConfigEntry<string> lastAppliedDifficultyPreset;

	private ConfigEntry<bool> showHud;

	private ConfigEntry<bool> hideHudWithCtrlF3;

	private ConfigEntry<bool> useCompactSurvivalHud;

	private ConfigEntry<KeyCode> hudLayoutEditorKey;

	private ConfigEntry<float> compactHudXNormalized;

	private ConfigEntry<float> compactHudYNormalized;

	private ConfigEntry<float> compactHudWidthNormalized;

	private ConfigEntry<float> compactHudHeightNormalized;

	private ConfigEntry<bool> debugLogging;

	private ConfigEntry<bool> enableLowTemperatureWarning;

	private ConfigEntry<float> lowTemperatureWarningThreshold;

	private ConfigEntry<float> lowTemperatureWarningRepeatSeconds;

	private ConfigEntry<float> lowTemperatureWarningVolume;

	private ConfigEntry<string> lowTemperatureWarningFile;

	private ConfigEntry<float> safeRecoveryRate;

	private ConfigEntry<float> nearFireWarmingRate;

	private ConfigEntry<float> wetCoolingRate;

	private ConfigEntry<float> coldEnvironmentCoolingRate;

	private ConfigEntry<float> freezingEnvironmentCoolingRate;

	private ConfigEntry<float> mountainCoolingRate;

	private ConfigEntry<float> deepNorthCoolingRate;

	private ConfigEntry<float> nightCoolingRate;

	private ConfigEntry<float> swimmingCoolingRate;

	private ConfigEntry<float> shelterCoolingMultiplier;

	private ConfigEntry<float> severeColdThreshold;

	private ConfigEntry<float> staminaDrainAtZero;

	private ConfigEntry<float> emergencyStaminaReserve;

	private ConfigEntry<float> freezingDamagePerSecond;

	private float temperature;

	private float tickTimer;

	private bool runtimeEnabled = true;

	private SurvivalSnapshot lastSnapshot;

	private bool hasSnapshot;

	private string pluginDirectory;

	private Component lowTemperatureAudioSource;

	private object lowTemperatureWarningClip;

	private bool lowTemperatureWarningLoadStarted;

	private bool wasBelowWarningThreshold;

	private float nextLowTemperatureWarningTime;

	private GUIStyle compactTemperatureHeaderStyle;

	private GUIStyle compactTemperatureDetailStyle;

	private bool hudLayoutEditorActive;

	private bool hudLayoutDragging;

	private HudResizeHandle hudResizeHandle;

	private Vector2 hudEditStartMouse;

	private Rect hudEditStartRect;

	private CursorLockMode hudPreviousCursorLockMode;

	private bool hudPreviousCursorVisible;

	private bool hudCursorStateCaptured;

	private bool hudHiddenByCtrlF3;

	private void Awake()
	{
		pluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Set false to disable the entire cold system, including temperature changes and penalties.");
		diagnosticKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "DiagnosticKey", (KeyCode)290, "Writes one diagnostic line to BepInEx/LogOutput.log.");
		sessionToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "SessionToggleKey", (KeyCode)291, "Emergency session toggle. This stops or restarts the cold system without removing the DLL.");
		tickInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TickIntervalSeconds", 1f, "How often the mod updates temperature. Lower values are smoother but use more CPU.");
		startingTemperature = ((BaseUnityPlugin)this).Config.Bind<float>("General", "StartingTemperature", 100f, "Temperature used when Valheim starts. Temperature is not saved between sessions in V0.1.");
		difficultyPreset = ((BaseUnityPlugin)this).Config.Bind<string>("Difficulty", "Preset", "Normal", "Choose Easy, Normal, Hard, or Extreme. Change this setting, then restart Valheim to apply that mod's matching survival balance.");
		lastAppliedDifficultyPreset = ((BaseUnityPlugin)this).Config.Bind<string>("Difficulty", "LastAppliedPreset", "Normal", "Internal preset tracking. Leave this alone; it records the last difficulty preset applied.");
		showHud = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "ShowTemperatureBar", true, "Set false to hide only the Body Temp HUD while the cold system continues running.");
		hideHudWithCtrlF3 = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "HideHudWithCtrlF3", true, "When enabled, Ctrl+F3 hides or restores this mod's HUD along with Valheim's HUD toggle. The cold system keeps running.");
		useCompactSurvivalHud = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "UseCompactSurvivalHud", true, "Places the compact Body Temp panel beneath Nourishment and directly left of the Tired meter.");
		hudLayoutEditorKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("HUD Layout Editor", "ToggleBodyTempLayoutEditorKey", (KeyCode)107, "Press K to enter or leave Body Temp HUD layout mode. In layout mode, drag the panel and drag a gold corner handle to resize it.");
		compactHudXNormalized = ((BaseUnityPlugin)this).Config.Bind<float>("HUD Layout", "CompactBodyTempXNormalized", 0.12060547f, "Saved left position of the compact Body Temp panel as a fraction of screen width.");
		compactHudYNormalized = ((BaseUnityPlugin)this).Config.Bind<float>("HUD Layout", "CompactBodyTempYNormalized", 61f / 72f, "Saved top position of the compact Body Temp panel as a fraction of screen height.");
		compactHudWidthNormalized = ((BaseUnityPlugin)this).Config.Bind<float>("HUD Layout", "CompactBodyTempWidthNormalized", 0.107910156f, "Saved width of the compact Body Temp panel as a fraction of screen width.");
		compactHudHeightNormalized = ((BaseUnityPlugin)this).Config.Bind<float>("HUD Layout", "CompactBodyTempHeightNormalized", 0.050347224f, "Saved height of the compact Body Temp panel as a fraction of screen height.");
		enableLowTemperatureWarning = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "EnableLowTemperatureWarning", true, "Plays the supplied cold-warning sound once when body temperature falls below the threshold, then only at a spaced interval while it remains low.");
		lowTemperatureWarningThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "LowTemperatureWarningThreshold", 40f, "Body temperature threshold that starts the low-temperature warning.");
		lowTemperatureWarningRepeatSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "LowTemperatureWarningRepeatSeconds", 150f, "Minimum number of real-time seconds between low-temperature warning repeats while temperature stays below the threshold.");
		lowTemperatureWarningVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "LowTemperatureWarningVolume", 0.55f, "Volume for the external cold-warning sound.");
		lowTemperatureWarningFile = ((BaseUnityPlugin)this).Config.Bind<string>("Audio", "LowTemperatureWarningFile", "cold breath.mp3", "MP3 filename expected in assets/audio beside the You're Cold DLL. The supplied default is cold breath.mp3.");
		debugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogging", false, "Writes one temperature line every update to LogOutput.log. Keep this off unless testing.");
		safeRecoveryRate = ((BaseUnityPlugin)this).Config.Bind<float>("Rates", "SafeRecoveryPerSecond", 0.35f, "Temperature recovered each second when dry, safe and not losing heat.");
		nearFireWarmingRate = ((BaseUnityPlugin)this).Config.Bind<float>("Rates", "NearFireWarmingPerSecond", 6f, "Temperature gained each second near Valheim's campfire/heat area.");
		wetCoolingRate = ((BaseUnityPlugin)this).Config.Bind<float>("Rates", "WetCoolingPerSecond", 0.2f, "Extra temperature lost each second while the player has Valheim's Wet status.");
		coldEnvironmentCoolingRate = ((BaseUnityPlugin)this).Config.Bind<float>("Rates", "ColdEnvironmentCoolingPerSecond", 0.18f, "Temperature lost each second when Valheim reports a cold environment.");
		freezingEnvironmentCoolingRate = ((BaseUnityPlugin)this).Config.Bind<float>("Rates", "FreezingEnvironmentCoolingPerSecond", 0.35f, "Temperature lost each second when Valheim reports a freezing environment.");
		mountainCoolingRate = ((BaseUnityPlugin)this).Config.Bind<float>("Rates", "MountainCoolingPerSecond", 0.15f, "Extra temperature lost each second in the Mountain biome.");
		deepNorthCoolingRate = ((BaseUnityPlugin)this).Config.Bind<float>("Rates", "DeepNorthCoolingPerSecond", 0.3f, "Extra temperature lost each second in the Deep North biome.");
		nightCoolingRate = ((BaseUnityPlugin)this).Config.Bind<float>("Rates", "NightCoolingPerSecond", 0.08f, "Extra temperature lost each second at night.");
		swimmingCoolingRate = ((BaseUnityPlugin)this).Config.Bind<float>("Rates", "SwimmingCoolingPerSecond", 2f, "Temperature lost each second while swimming. Swimming replaces smaller normal cooling sources.");
		shelterCoolingMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Rates", "ShelterCoolingMultiplier", 0.3f, "Multiplier applied to cooling while sheltered. 0.30 means shelter reduces cooling by 70 percent.");
		severeColdThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Penalties", "SevereColdThreshold", 15f, "Below this temperature, the player slowly loses stamina.");
		staminaDrainAtZero = ((BaseUnityPlugin)this).Config.Bind<float>("Penalties", "StaminaDrainAtZeroPerSecond", 0.8f, "Stamina removed per second at 0 temperature. The drain scales from zero at SevereColdThreshold.");
		emergencyStaminaReserve = ((BaseUnityPlugin)this).Config.Bind<float>("Safety", "EmergencyStaminaReserve", 12f, "Cold never directly spends stamina below this reserve. Conditions can still make escape difficult, but cold alone cannot erase the last usable burst of stamina.");
		freezingDamagePerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Penalties", "FreezingDamageAtZeroPerSecond", 0.25f, "Health removed per second at 0 temperature. This is deliberately mild in V0.1 for safe testing.");
		temperature = Mathf.Clamp(startingTemperature.Value, 0f, 100f);
		MigrateLegacyDefaultsToNormal();
		ApplyDifficultyPresetIfChanged();
		((MonoBehaviour)this).StartCoroutine(LoadLowTemperatureWarningAudio());
		((BaseUnityPlugin)this).Logger.LogInfo((object)"You're Cold 0.3.0 loaded. F9 writes a diagnostic line. F10 safely toggles the cold system for this session.");
	}

	private void Update()
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		if (TryToggleHudWithCtrlF3())
		{
			return;
		}
		if (hudLayoutEditorActive && (!showHud.Value || IsHudHiddenByCtrlF3()))
		{
			CloseHudLayoutEditorForHiddenHud();
		}
		if (Input.GetKeyDown(hudLayoutEditorKey.Value) && showHud.Value && !IsHudHiddenByCtrlF3())
		{
			ToggleHudLayoutEditor();
		}
		if (Input.GetKeyDown(diagnosticKey.Value))
		{
			WriteDiagnostic();
		}
		if (Input.GetKeyDown(sessionToggleKey.Value))
		{
			runtimeEnabled = !runtimeEnabled;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("You're Cold session toggle: " + (runtimeEnabled ? "ON" : "OFF") + "."));
		}
		if (!runtimeEnabled || !modEnabled.Value)
		{
			return;
		}
		float num = Mathf.Max(0.1f, tickInterval.Value);
		tickTimer += Time.deltaTime;
		if (tickTimer < num)
		{
			return;
		}
		float elapsedSeconds = Mathf.Min(tickTimer, num * 3f);
		tickTimer = 0f;
		try
		{
			Tick(elapsedSeconds);
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("You're Cold update failed: " + ex));
		}
	}

	private void Tick(float elapsedSeconds)
	{
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null))
		{
			SurvivalSnapshot snapshot = (lastSnapshot = ReadSnapshot(localPlayer));
			hasSnapshot = true;
			TemperatureSettings settings = ReadTemperatureSettings();
			float temperatureRate = TemperatureRules.GetTemperatureRate(snapshot, settings);
			temperature = Mathf.Clamp(temperature + temperatureRate * elapsedSeconds, 0f, 100f);
			ApplyColdPenalties(localPlayer, elapsedSeconds);
			UpdateLowTemperatureWarning();
			if (debugLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Temperature=" + temperature.ToString("0.0") + ", rate=" + temperatureRate.ToString("0.00") + "/s, " + snapshot.ToDiagnosticText()));
			}
		}
	}

	private SurvivalSnapshot ReadSnapshot(Player player)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Invalid comparison between Unknown and I4
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Invalid comparison between Unknown and I4
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		SEMan sEMan = ((Character)player).GetSEMan();
		Biome currentBiome = player.GetCurrentBiome();
		bool isWet = sEMan != null && sEMan.HaveStatusEffect(SEMan.s_statusEffectWet);
		bool flag = sEMan != null && sEMan.HaveStatusEffect(SEMan.s_statusEffectCampFire);
		bool flag2 = (Object)(object)EffectArea.IsPointInsideArea(((Component)player).transform.position, (Type)1, 0f) != (Object)null;
		return new SurvivalSnapshot(((Character)player).IsSwimming(), player.InShelter(), isWet, flag || flag2, EnvMan.IsCold(), EnvMan.IsFreezing(), EnvMan.IsNight(), (currentBiome & 4) > 0, (currentBiome & 0x40) > 0, currentBiome);
	}

	private TemperatureSettings ReadTemperatureSettings()
	{
		return new TemperatureSettings(Mathf.Max(0f, safeRecoveryRate.Value), Mathf.Max(0f, nearFireWarmingRate.Value), Mathf.Max(0f, wetCoolingRate.Value), Mathf.Max(0f, coldEnvironmentCoolingRate.Value), Mathf.Max(0f, freezingEnvironmentCoolingRate.Value), Mathf.Max(0f, mountainCoolingRate.Value), Mathf.Max(0f, deepNorthCoolingRate.Value), Mathf.Max(0f, nightCoolingRate.Value), Mathf.Max(0f, swimmingCoolingRate.Value), Mathf.Clamp(shelterCoolingMultiplier.Value, 0f, 1f));
	}

	private void ApplyColdPenalties(Player player, float elapsedSeconds)
	{
		float num = Mathf.Clamp(severeColdThreshold.Value, 0.01f, 100f);
		if (temperature <= num)
		{
			float num2 = 1f - temperature / num;
			float num3 = Mathf.Max(0f, staminaDrainAtZero.Value) * num2 * elapsedSeconds;
			float num4 = Mathf.Clamp(emergencyStaminaReserve.Value, 0f, 50f);
			float num5 = Mathf.Max(0f, player.GetStamina() - num4);
			if (num3 > 0f && num5 > 0f)
			{
				((Character)player).UseStamina(Mathf.Min(num3, num5));
			}
		}
		if (temperature <= 0.01f)
		{
			float num6 = Mathf.Max(0f, freezingDamagePerSecond.Value) * elapsedSeconds;
			if (num6 > 0f && ((Character)player).GetHealth() > 0f)
			{
				((Character)player).UseHealth(Mathf.Min(num6, ((Character)player).GetHealth()));
			}
		}
	}

	private void MigrateLegacyDefaultsToNormal()
	{
		if (Mathf.Abs(safeRecoveryRate.Value - 0.25f) < 0.001f && Mathf.Abs(wetCoolingRate.Value - 0.35f) < 0.001f && Mathf.Abs(coldEnvironmentCoolingRate.Value - 0.3f) < 0.001f && Mathf.Abs(freezingEnvironmentCoolingRate.Value - 0.65f) < 0.001f && Mathf.Abs(mountainCoolingRate.Value - 0.25f) < 0.001f && Mathf.Abs(deepNorthCoolingRate.Value - 0.45f) < 0.001f && Mathf.Abs(nightCoolingRate.Value - 0.12f) < 0.001f && Mathf.Abs(swimmingCoolingRate.Value - 3f) < 0.001f && Mathf.Abs(shelterCoolingMultiplier.Value - 0.45f) < 0.001f && Mathf.Abs(severeColdThreshold.Value - 25f) < 0.001f && Mathf.Abs(staminaDrainAtZero.Value - 3f) < 0.001f)
		{
			ApplyDifficultyPreset("Normal");
			((BaseUnityPlugin)this).Config.Save();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"You're Cold: migrated untouched legacy cold defaults to the balanced Normal preset.");
		}
	}

	private void ApplyDifficultyPresetIfChanged()
	{
		string text = NormalizeDifficultyPreset(difficultyPreset.Value);
		if (!string.Equals(difficultyPreset.Value, text, StringComparison.OrdinalIgnoreCase))
		{
			difficultyPreset.Value = text;
		}
		if (!string.Equals(lastAppliedDifficultyPreset.Value, text, StringComparison.OrdinalIgnoreCase))
		{
			ApplyDifficultyPreset(text);
			lastAppliedDifficultyPreset.Value = text;
			((BaseUnityPlugin)this).Config.Save();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("You're Cold: applied " + text + " difficulty preset."));
		}
	}

	private static string NormalizeDifficultyPreset(string value)
	{
		if (string.Equals(value, "Easy", StringComparison.OrdinalIgnoreCase))
		{
			return "Easy";
		}
		if (string.Equals(value, "Hard", StringComparison.OrdinalIgnoreCase))
		{
			return "Hard";
		}
		if (string.Equals(value, "Extreme", StringComparison.OrdinalIgnoreCase))
		{
			return "Extreme";
		}
		return "Normal";
	}

	private void ApplyDifficultyPreset(string preset)
	{
		switch (preset)
		{
		case "Easy":
			safeRecoveryRate.Value = 0.48f;
			nearFireWarmingRate.Value = 7f;
			wetCoolingRate.Value = 0.12f;
			coldEnvironmentCoolingRate.Value = 0.11f;
			freezingEnvironmentCoolingRate.Value = 0.22f;
			mountainCoolingRate.Value = 0.1f;
			deepNorthCoolingRate.Value = 0.18f;
			nightCoolingRate.Value = 0.05f;
			swimmingCoolingRate.Value = 1.45f;
			shelterCoolingMultiplier.Value = 0.22f;
			severeColdThreshold.Value = 10f;
			staminaDrainAtZero.Value = 0.45f;
			emergencyStaminaReserve.Value = 14f;
			freezingDamagePerSecond.Value = 0.15f;
			break;
		case "Hard":
			safeRecoveryRate.Value = 0.25f;
			nearFireWarmingRate.Value = 5.5f;
			wetCoolingRate.Value = 0.3f;
			coldEnvironmentCoolingRate.Value = 0.27f;
			freezingEnvironmentCoolingRate.Value = 0.5f;
			mountainCoolingRate.Value = 0.23f;
			deepNorthCoolingRate.Value = 0.42f;
			nightCoolingRate.Value = 0.12f;
			swimmingCoolingRate.Value = 2.7f;
			shelterCoolingMultiplier.Value = 0.42f;
			severeColdThreshold.Value = 20f;
			staminaDrainAtZero.Value = 1.15f;
			emergencyStaminaReserve.Value = 10f;
			freezingDamagePerSecond.Value = 0.32f;
			break;
		case "Extreme":
			safeRecoveryRate.Value = 0.18f;
			nearFireWarmingRate.Value = 4.6f;
			wetCoolingRate.Value = 0.42f;
			coldEnvironmentCoolingRate.Value = 0.38f;
			freezingEnvironmentCoolingRate.Value = 0.72f;
			mountainCoolingRate.Value = 0.35f;
			deepNorthCoolingRate.Value = 0.6f;
			nightCoolingRate.Value = 0.18f;
			swimmingCoolingRate.Value = 3.4f;
			shelterCoolingMultiplier.Value = 0.58f;
			severeColdThreshold.Value = 25f;
			staminaDrainAtZero.Value = 1.35f;
			emergencyStaminaReserve.Value = 8f;
			freezingDamagePerSecond.Value = 0.42f;
			break;
		default:
			safeRecoveryRate.Value = 0.35f;
			nearFireWarmingRate.Value = 6f;
			wetCoolingRate.Value = 0.2f;
			coldEnvironmentCoolingRate.Value = 0.18f;
			freezingEnvironmentCoolingRate.Value = 0.35f;
			mountainCoolingRate.Value = 0.15f;
			deepNorthCoolingRate.Value = 0.3f;
			nightCoolingRate.Value = 0.08f;
			swimmingCoolingRate.Value = 2f;
			shelterCoolingMultiplier.Value = 0.3f;
			severeColdThreshold.Value = 15f;
			staminaDrainAtZero.Value = 0.8f;
			emergencyStaminaReserve.Value = 12f;
			freezingDamagePerSecond.Value = 0.25f;
			break;
		}
	}

	private void WriteDiagnostic()
	{
		if (!hasSnapshot)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"You're Cold: no player temperature snapshot has been collected yet.");
			return;
		}
		float temperatureRate = TemperatureRules.GetTemperatureRate(lastSnapshot, ReadTemperatureSettings());
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Diagnostic: temperature=" + temperature.ToString("0.0") + "/100, rate=" + temperatureRate.ToString("0.00") + "/s, " + lastSnapshot.ToDiagnosticText()));
	}

	private void OnGUI()
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_0259: 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_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dc: 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)
		if (runtimeEnabled && modEnabled.Value && showHud.Value && !IsHudHiddenByCtrlF3() && !((Object)(object)Player.m_localPlayer == (Object)null))
		{
			if (!useCompactSurvivalHud.Value)
			{
				DrawLegacyTemperatureHud();
				return;
			}
			Rect compactHudRect = GetCompactHudRect();
			float compactHudContentScale = GetCompactHudContentScale(compactHudRect);
			float num = Mathf.Max(1f, ((Rect)(ref compactHudRect)).width - 8f * compactHudContentScale);
			float num2 = num * (temperature / 100f);
			EnsureCompactHudStyles(compactHudContentScale);
			Color color = GUI.color;
			GUI.color = new Color(0f, 0f, 0f, 0.84f);
			GUI.DrawTexture(compactHudRect, (Texture)(object)Texture2D.whiteTexture);
			GUI.color = new Color(0.78f, 0.72f, 0.53f, 0.68f);
			GUI.DrawTexture(new Rect(((Rect)(ref compactHudRect)).x, ((Rect)(ref compactHudRect)).y, ((Rect)(ref compactHudRect)).width, 1f * compactHudContentScale), (Texture)(object)Texture2D.whiteTexture);
			GUI.DrawTexture(new Rect(((Rect)(ref compactHudRect)).x, ((Rect)(ref compactHudRect)).yMax - 1f * compactHudContentScale, ((Rect)(ref compactHudRect)).width, 1f * compactHudContentScale), (Texture)(object)Texture2D.whiteTexture);
			GUI.DrawTexture(new Rect(((Rect)(ref compactHudRect)).x, ((Rect)(ref compactHudRect)).y, 1f * compactHudContentScale, ((Rect)(ref compactHudRect)).height), (Texture)(object)Texture2D.whiteTexture);
			GUI.DrawTexture(new Rect(((Rect)(ref compactHudRect)).xMax - 1f * compactHudContentScale, ((Rect)(ref compactHudRect)).y, 1f * compactHudContentScale, ((Rect)(ref compactHudRect)).height), (Texture)(object)Texture2D.whiteTexture);
			GUI.color = Color.white;
			GUI.Label(new Rect(((Rect)(ref compactHudRect)).x + 7f * compactHudContentScale, ((Rect)(ref compactHudRect)).y + 4f * compactHudContentScale, ((Rect)(ref compactHudRect)).width - 14f * compactHudContentScale, 16f * compactHudContentScale), "Body Temp " + temperature.ToString("0") + "%", compactTemperatureHeaderStyle);
			GUI.color = new Color(0f, 0f, 0f, 0.56f);
			GUI.DrawTexture(new Rect(((Rect)(ref compactHudRect)).x + 4f * compactHudContentScale, ((Rect)(ref compactHudRect)).y + 24f * compactHudContentScale, num, 14f * compactHudContentScale), (Texture)(object)Texture2D.whiteTexture);
			GUI.color = GetTemperatureColor(temperature);
			GUI.DrawTexture(new Rect(((Rect)(ref compactHudRect)).x + 4f * compactHudContentScale, ((Rect)(ref compactHudRect)).y + 24f * compactHudContentScale, num2, 14f * compactHudContentScale), (Texture)(object)Texture2D.whiteTexture);
			GUI.color = GetTemperatureColor(temperature);
			GUI.Label(new Rect(((Rect)(ref compactHudRect)).x + 7f * compactHudContentScale, ((Rect)(ref compactHudRect)).y + 40f * compactHudContentScale, ((Rect)(ref compactHudRect)).width - 14f * compactHudContentScale, 13f * compactHudContentScale), GetTemperatureLabel(temperature), compactTemperatureDetailStyle);
			GUI.color = color;
			DrawHudLayoutEditor(compactHudRect);
		}
	}

	private void DrawLegacyTemperatureHud()
	{
		//IL_0032: 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_004c: 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_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		float num = ((float)Screen.width - 220f) * 0.5f;
		float num2 = (float)Screen.height - 118f;
		float num3 = 216f * (temperature / 100f);
		Color color = GUI.color;
		GUI.color = new Color(0f, 0f, 0f, 0.7f);
		GUI.DrawTexture(new Rect(num, num2, 220f, 18f), (Texture)(object)Texture2D.whiteTexture);
		GUI.color = GetTemperatureColor(temperature);
		GUI.DrawTexture(new Rect(num + 2f, num2 + 2f, num3, 14f), (Texture)(object)Texture2D.whiteTexture);
		GUI.color = Color.white;
		GUI.Label(new Rect(num, num2 - 21f, 220f, 20f), "Temperature: " + temperature.ToString("0") + "% - " + GetTemperatureLabel(temperature));
		GUI.color = color;
	}

	private static float GetCompactHudScale()
	{
		return Mathf.Max(0.7f, Mathf.Min((float)Screen.width / 2048f, (float)Screen.height / 1152f));
	}

	private Rect GetCompactHudRect()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		float compactHudScale = GetCompactHudScale();
		float minimumWidth = 145f * compactHudScale;
		float minimumHeight = 44f * compactHudScale;
		return ClampHudRect(new Rect(compactHudXNormalized.Value * (float)Screen.width, compactHudYNormalized.Value * (float)Screen.height, compactHudWidthNormalized.Value * (float)Screen.width, compactHudHeightNormalized.Value * (float)Screen.height), minimumWidth, minimumHeight);
	}

	private float GetCompactHudContentScale(Rect panelRect)
	{
		float compactHudScale = GetCompactHudScale();
		float num = 221f * compactHudScale;
		float num2 = 58f * compactHudScale;
		float num3 = Mathf.Min(((Rect)(ref panelRect)).width / num, ((Rect)(ref panelRect)).height / num2);
		return Mathf.Max(0.55f, compactHudScale * Mathf.Clamp(num3, 0.55f, 3f));
	}

	private void StoreCompactHudRect(Rect rect)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		Rect val = ClampHudRect(rect, 145f * GetCompactHudScale(), 44f * GetCompactHudScale());
		compactHudXNormalized.Value = ((Rect)(ref val)).x / Mathf.Max(1f, (float)Screen.width);
		compactHudYNormalized.Value = ((Rect)(ref val)).y / Mathf.Max(1f, (float)Screen.height);
		compactHudWidthNormalized.Value = ((Rect)(ref val)).width / Mathf.Max(1f, (float)Screen.width);
		compactHudHeightNormalized.Value = ((Rect)(ref val)).height / Mathf.Max(1f, (float)Screen.height);
	}

	private static Rect ClampHudRect(Rect rect, float minimumWidth, float minimumHeight)
	{
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Clamp(((Rect)(ref rect)).width, minimumWidth, Mathf.Max(minimumWidth, (float)Screen.width - 4f));
		float num2 = Mathf.Clamp(((Rect)(ref rect)).height, minimumHeight, Mathf.Max(minimumHeight, (float)Screen.height - 4f));
		float num3 = Mathf.Clamp(((Rect)(ref rect)).x, 0f, Mathf.Max(0f, (float)Screen.width - num));
		float num4 = Mathf.Clamp(((Rect)(ref rect)).y, 0f, Mathf.Max(0f, (float)Screen.height - num2));
		return new Rect(num3, num4, num, num2);
	}

	private bool IsHudHiddenByCtrlF3()
	{
		if (hideHudWithCtrlF3 != null && hideHudWithCtrlF3.Value)
		{
			return hudHiddenByCtrlF3;
		}
		return false;
	}

	private bool TryToggleHudWithCtrlF3()
	{
		if (!IsCtrlF3Pressed())
		{
			return false;
		}
		if (hideHudWithCtrlF3 == null || !hideHudWithCtrlF3.Value)
		{
			return true;
		}
		hudHiddenByCtrlF3 = !hudHiddenByCtrlF3;
		if (hudHiddenByCtrlF3)
		{
			CloseHudLayoutEditorForHiddenHud();
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)("You're Cold: Ctrl+F3 HUD " + (hudHiddenByCtrlF3 ? "hidden." : "restored.")));
		return true;
	}

	private static bool IsCtrlF3Pressed()
	{
		if (Input.GetKeyDown((KeyCode)284))
		{
			if (!Input.GetKey((KeyCode)306))
			{
				return Input.GetKey((KeyCode)305);
			}
			return true;
		}
		return false;
	}

	private void CloseHudLayoutEditorForHiddenHud()
	{
		if (hudLayoutEditorActive)
		{
			hudLayoutEditorActive = false;
			hudLayoutDragging = false;
			hudResizeHandle = HudResizeHandle.None;
			RestoreHudCursor();
			((BaseUnityPlugin)this).Config.Save();
		}
	}

	private void ToggleHudLayoutEditor()
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		hudLayoutEditorActive = !hudLayoutEditorActive;
		hudLayoutDragging = false;
		hudResizeHandle = HudResizeHandle.None;
		if (hudLayoutEditorActive)
		{
			hudPreviousCursorLockMode = Cursor.lockState;
			hudPreviousCursorVisible = Cursor.visible;
			hudCursorStateCaptured = true;
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"You're Cold: Body Temp HUD layout editor enabled. Drag the panel or a gold corner; press K again to save and exit.");
		}
		else
		{
			RestoreHudCursor();
			((BaseUnityPlugin)this).Config.Save();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"You're Cold: Body Temp HUD layout editor saved and closed.");
		}
	}

	private void RestoreHudCursor()
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		if (hudCursorStateCaptured)
		{
			Cursor.lockState = hudPreviousCursorLockMode;
			Cursor.visible = hudPreviousCursorVisible;
			hudCursorStateCaptured = false;
		}
	}

	private void DrawHudLayoutEditor(Rect panelRect)
	{
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Invalid comparison between Unknown and I4
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Invalid comparison between Unknown and I4
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		if (!hudLayoutEditorActive)
		{
			return;
		}
		Cursor.lockState = (CursorLockMode)0;
		Cursor.visible = true;
		Event current = Event.current;
		if (current != null)
		{
			Vector2 mousePosition = current.mousePosition;
			if ((int)current.type == 0 && current.button == 0)
			{
				HudResizeHandle resizeHandle = GetResizeHandle(panelRect, mousePosition);
				if (resizeHandle != HudResizeHandle.None)
				{
					hudResizeHandle = resizeHandle;
					hudLayoutDragging = false;
					hudEditStartMouse = mousePosition;
					hudEditStartRect = panelRect;
					current.Use();
				}
				else if (((Rect)(ref panelRect)).Contains(mousePosition))
				{
					hudLayoutDragging = true;
					hudResizeHandle = HudResizeHandle.None;
					hudEditStartMouse = mousePosition;
					hudEditStartRect = panelRect;
					current.Use();
				}
			}
			else if ((int)current.type == 3 && current.button == 0 && (hudLayoutDragging || hudResizeHandle != HudResizeHandle.None))
			{
				Vector2 val = mousePosition - hudEditStartMouse;
				Rect rect = (Rect)(hudLayoutDragging ? new Rect(((Rect)(ref hudEditStartRect)).x + val.x, ((Rect)(ref hudEditStartRect)).y + val.y, ((Rect)(ref hudEditStartRect)).width, ((Rect)(ref hudEditStartRect)).height) : ResizeRect(hudEditStartRect, val, hudResizeHandle, 145f * GetCompactHudScale(), 44f * GetCompactHudScale()));
				StoreCompactHudRect(rect);
				current.Use();
			}
			else if ((int)current.type == 1 && current.button == 0 && (hudLayoutDragging || hudResizeHandle != HudResizeHandle.None))
			{
				hudLayoutDragging = false;
				hudResizeHandle = HudResizeHandle.None;
				((BaseUnityPlugin)this).Config.Save();
				current.Use();
			}
		}
		DrawEditorOutline(panelRect);
		Color color = GUI.color;
		GUI.color = new Color(1f, 0.78f, 0.22f, 1f);
		GUI.Label(new Rect(12f, 12f, 820f, 24f), "K — Body Temp layout mode: drag panel; drag any gold corner to resize; press K again to save.");
		GUI.color = color;
	}

	private static HudResizeHandle GetResizeHandle(Rect rect, Vector2 mouse)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		Rect val = new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, 14f, 14f);
		if (((Rect)(ref val)).Contains(mouse))
		{
			return HudResizeHandle.TopLeft;
		}
		val = new Rect(((Rect)(ref rect)).xMax - 14f, ((Rect)(ref rect)).y, 14f, 14f);
		if (((Rect)(ref val)).Contains(mouse))
		{
			return HudResizeHandle.TopRight;
		}
		val = new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).yMax - 14f, 14f, 14f);
		if (((Rect)(ref val)).Contains(mouse))
		{
			return HudResizeHandle.BottomLeft;
		}
		val = new Rect(((Rect)(ref rect)).xMax - 14f, ((Rect)(ref rect)).yMax - 14f, 14f, 14f);
		if (((Rect)(ref val)).Contains(mouse))
		{
			return HudResizeHandle.BottomRight;
		}
		return HudResizeHandle.None;
	}

	private static Rect ResizeRect(Rect start, Vector2 delta, HudResizeHandle handle, float minimumWidth, float minimumHeight)
	{
		//IL_0029: 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_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		float num = ((Rect)(ref start)).x;
		float num2 = ((Rect)(ref start)).y;
		float num3 = ((Rect)(ref start)).width;
		float num4 = ((Rect)(ref start)).height;
		switch (handle)
		{
		case HudResizeHandle.TopLeft:
		case HudResizeHandle.BottomLeft:
			num += delta.x;
			num3 -= delta.x;
			break;
		case HudResizeHandle.TopRight:
		case HudResizeHandle.BottomRight:
			num3 += delta.x;
			break;
		}
		switch (handle)
		{
		case HudResizeHandle.TopLeft:
		case HudResizeHandle.TopRight:
			num2 += delta.y;
			num4 -= delta.y;
			break;
		case HudResizeHandle.BottomLeft:
		case HudResizeHandle.BottomRight:
			num4 += delta.y;
			break;
		}
		if (num3 < minimumWidth)
		{
			if (handle == HudResizeHandle.TopLeft || handle == HudResizeHandle.BottomLeft)
			{
				num = ((Rect)(ref start)).xMax - minimumWidth;
			}
			num3 = minimumWidth;
		}
		if (num4 < minimumHeight)
		{
			if (handle == HudResizeHandle.TopLeft || handle == HudResizeHandle.TopRight)
			{
				num2 = ((Rect)(ref start)).yMax - minimumHeight;
			}
			num4 = minimumHeight;
		}
		return ClampHudRect(new Rect(num, num2, num3, num4), minimumWidth, minimumHeight);
	}

	private static void DrawEditorOutline(Rect rect)
	{
		//IL_0000: 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_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		Color color = GUI.color;
		GUI.color = new Color(1f, 0.72f, 0.15f, 0.95f);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x - 1f, ((Rect)(ref rect)).y - 1f, ((Rect)(ref rect)).width + 2f, 2f), (Texture)(object)Texture2D.whiteTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x - 1f, ((Rect)(ref rect)).yMax - 1f, ((Rect)(ref rect)).width + 2f, 2f), (Texture)(object)Texture2D.whiteTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x - 1f, ((Rect)(ref rect)).y - 1f, 2f, ((Rect)(ref rect)).height + 2f), (Texture)(object)Texture2D.whiteTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMax - 1f, ((Rect)(ref rect)).y - 1f, 2f, ((Rect)(ref rect)).height + 2f), (Texture)(object)Texture2D.whiteTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x - 2f, ((Rect)(ref rect)).y - 2f, 8f, 8f), (Texture)(object)Texture2D.whiteTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMax - 6f, ((Rect)(ref rect)).y - 2f, 8f, 8f), (Texture)(object)Texture2D.whiteTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x - 2f, ((Rect)(ref rect)).yMax - 6f, 8f, 8f), (Texture)(object)Texture2D.whiteTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMax - 6f, ((Rect)(ref rect)).yMax - 6f, 8f, 8f), (Texture)(object)Texture2D.whiteTexture);
		GUI.color = color;
	}

	private void EnsureCompactHudStyles(float scale)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Expected O, but got Unknown
		if (compactTemperatureHeaderStyle == null)
		{
			compactTemperatureHeaderStyle = new GUIStyle(GUI.skin.label);
			compactTemperatureHeaderStyle.fontStyle = (FontStyle)0;
			compactTemperatureHeaderStyle.wordWrap = false;
			compactTemperatureHeaderStyle.clipping = (TextClipping)1;
			compactTemperatureHeaderStyle.alignment = (TextAnchor)0;
		}
		if (compactTemperatureDetailStyle == null)
		{
			compactTemperatureDetailStyle = new GUIStyle(GUI.skin.label);
			compactTemperatureDetailStyle.wordWrap = false;
			compactTemperatureDetailStyle.clipping = (TextClipping)1;
			compactTemperatureDetailStyle.alignment = (TextAnchor)0;
		}
		compactTemperatureHeaderStyle.fontSize = Mathf.Max(10, Mathf.RoundToInt(12f * scale));
		compactTemperatureDetailStyle.fontSize = Mathf.Max(9, Mathf.RoundToInt(10.5f * scale));
	}

	private void UpdateLowTemperatureWarning()
	{
		if (enableLowTemperatureWarning.Value && lowTemperatureWarningClip != null)
		{
			float num = Mathf.Clamp(lowTemperatureWarningThreshold.Value, 1f, 100f);
			float num2 = Mathf.Min(100f, num + 2f);
			if (temperature >= num2)
			{
				wasBelowWarningThreshold = false;
			}
			else if (!(temperature > num) && (!wasBelowWarningThreshold || Time.unscaledTime >= nextLowTemperatureWarningTime) && TryPlayOneShot(lowTemperatureWarningClip, Mathf.Clamp01(lowTemperatureWarningVolume.Value)))
			{
				wasBelowWarningThreshold = true;
				nextLowTemperatureWarningTime = Time.unscaledTime + Mathf.Max(30f, lowTemperatureWarningRepeatSeconds.Value);
			}
		}
	}

	private IEnumerator LoadLowTemperatureWarningAudio()
	{
		if (!lowTemperatureWarningLoadStarted)
		{
			lowTemperatureWarningLoadStarted = true;
			string path = (string.IsNullOrWhiteSpace(lowTemperatureWarningFile.Value) ? "cold breath.mp3" : lowTemperatureWarningFile.Value.Trim());
			string path2 = Path.Combine(pluginDirectory ?? string.Empty, "assets", "audio", path);
			yield return ((MonoBehaviour)this).StartCoroutine(LoadExternalMp3(path2, delegate(object clip)
			{
				lowTemperatureWarningClip = clip;
			}, "cold warning"));
		}
	}

	private IEnumerator LoadExternalMp3(string path, Action<object> onLoaded, string label)
	{
		object request;
		object operation;
		if (string.IsNullOrEmpty(path) || !File.Exists(path))
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Cold: " + label + " audio file was not found at " + path));
		}
		else if (TryBeginExternalMp3Request(path, label, out request, out operation))
		{
			yield return operation;
			CompleteExternalMp3Request(request, onLoaded, label);
		}
	}

	private bool TryBeginExternalMp3Request(string path, string label, out object request, out object operation)
	{
		request = null;
		operation = null;
		try
		{
			Type type = FindRuntimeType("UnityEngine.Networking.UnityWebRequestMultimedia");
			if (type == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Cold: UnityWebRequestMultimedia was unavailable; could not load " + label + " audio."));
				return false;
			}
			MethodInfo methodInfo = null;
			MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo methodInfo2 in methods)
			{
				if (methodInfo2.Name == "GetAudioClip" && methodInfo2.GetParameters().Length == 2)
				{
					methodInfo = methodInfo2;
					break;
				}
			}
			if (methodInfo == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Cold: no compatible GetAudioClip method was found for " + label + " audio."));
				return false;
			}
			object obj = Enum.Parse(methodInfo.GetParameters()[1].ParameterType, "MPEG");
			request = methodInfo.Invoke(null, new object[2]
			{
				new Uri(path).AbsoluteUri,
				obj
			});
			if (request == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Cold: could not create the request for " + label + " audio."));
				return false;
			}
			MethodInfo method = request.GetType().GetMethod("SendWebRequest", Type.EmptyTypes);
			if (method == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Cold: no SendWebRequest method was found for " + label + " audio."));
				DisposeRequest(request);
				request = null;
				return false;
			}
			operation = method.Invoke(request, null);
			if (operation == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Cold: SendWebRequest returned no operation for " + label + " audio."));
				DisposeRequest(request);
				request = null;
				return false;
			}
			return true;
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Cold: could not start loading " + label + " audio. " + ex.Message));
			DisposeRequest(request);
			request = null;
			operation = null;
			return false;
		}
	}

	private void CompleteExternalMp3Request(object request, Action<object> onLoaded, string label)
	{
		try
		{
			if (request == null)
			{
				return;
			}
			PropertyInfo property = request.GetType().GetProperty("error", BindingFlags.Instance | BindingFlags.Public);
			string text = ((property != null) ? (property.GetValue(request, null) as string) : null);
			if (!string.IsNullOrEmpty(text))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Cold: failed to load " + label + " audio. " + text));
				return;
			}
			PropertyInfo property2 = request.GetType().GetProperty("downloadHandler", BindingFlags.Instance | BindingFlags.Public);
			object obj = ((property2 != null) ? property2.GetValue(request, null) : null);
			PropertyInfo propertyInfo = obj?.GetType().GetProperty("audioClip", BindingFlags.Instance | BindingFlags.Public);
			object obj2 = ((propertyInfo != null) ? propertyInfo.GetValue(obj, null) : null);
			if (obj2 == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Cold: the " + label + " MP3 decoded without an AudioClip."));
				return;
			}
			onLoaded?.Invoke(obj2);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("You're Cold: loaded " + label + " audio from " + Path.GetFileName(GetRequestUrl(request)) + "."));
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Cold: could not finish loading " + label + " audio. " + ex.Message));
		}
		finally
		{
			DisposeRequest(request);
		}
	}

	private static string GetRequestUrl(object request)
	{
		if (request == null)
		{
			return string.Empty;
		}
		try
		{
			PropertyInfo property = request.GetType().GetProperty("url", BindingFlags.Instance | BindingFlags.Public);
			string text = ((property != null) ? (property.GetValue(request, null) as string) : null);
			return string.IsNullOrEmpty(text) ? string.Empty : text;
		}
		catch
		{
			return string.Empty;
		}
	}

	private static void DisposeRequest(object request)
	{
		if (request is IDisposable disposable)
		{
			disposable.Dispose();
		}
	}

	private bool TryPlayOneShot(object clip, float volume)
	{
		if (clip == null)
		{
			return false;
		}
		Component val = EnsureLowTemperatureAudioSource();
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		try
		{
			MethodInfo[] methods = ((object)val).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name == "PlayOneShot" && methodInfo.GetParameters().Length == 2)
				{
					methodInfo.Invoke(val, new object[2] { clip, volume });
					return true;
				}
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Cold: failed to play low-temperature warning. " + ex.Message));
		}
		return false;
	}

	private Component EnsureLowTemperatureAudioSource()
	{
		if ((Object)(object)lowTemperatureAudioSource != (Object)null)
		{
			return lowTemperatureAudioSource;
		}
		Type type = FindRuntimeType("UnityEngine.AudioSource");
		if (type == null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"You're Cold: Unity AudioSource was unavailable.");
			return null;
		}
		lowTemperatureAudioSource = ((Component)this).gameObject.GetComponent(type);
		if ((Object)(object)lowTemperatureAudioSource == (Object)null)
		{
			lowTemperatureAudioSource = ((Component)this).gameObject.AddComponent(type);
		}
		if ((Object)(object)lowTemperatureAudioSource != (Object)null)
		{
			SetAudioProperty(lowTemperatureAudioSource, "playOnAwake", false);
			SetAudioProperty(lowTemperatureAudioSource, "spatialBlend", 0f);
			SetAudioProperty(lowTemperatureAudioSource, "loop", false);
		}
		return lowTemperatureAudioSource;
	}

	private static void SetAudioProperty(Component source, string name, object value)
	{
		if (!((Object)(object)source == (Object)null))
		{
			PropertyInfo property = ((object)source).GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Public);
			if (property != null && property.CanWrite)
			{
				property.SetValue(source, value, null);
			}
		}
	}

	private static Type FindRuntimeType(string fullName)
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		for (int i = 0; i < assemblies.Length; i++)
		{
			Type type = assemblies[i].GetType(fullName, throwOnError: false);
			if (type != null)
			{
				return type;
			}
		}
		string text = null;
		if (string.Equals(fullName, "UnityEngine.AudioSource", StringComparison.Ordinal))
		{
			text = "UnityEngine.AudioModule";
		}
		else if (fullName.StartsWith("UnityEngine.Networking.", StringComparison.Ordinal))
		{
			text = "UnityEngine.UnityWebRequestAudioModule";
		}
		if (!string.IsNullOrEmpty(text))
		{
			try
			{
				Assembly assembly = Assembly.Load(text);
				Type type2 = ((assembly != null) ? assembly.GetType(fullName, throwOnError: false) : null);
				if (type2 != null)
				{
					return type2;
				}
			}
			catch
			{
			}
		}
		return null;
	}

	private void OnDestroy()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Expected O, but got Unknown
		RestoreHudCursor();
		if (lowTemperatureWarningClip is Object)
		{
			Object.Destroy((Object)lowTemperatureWarningClip);
		}
	}

	private static Color GetTemperatureColor(float value)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: 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_0060: Unknown result type (might be due to invalid IL or missing references)
		if (value > 70f)
		{
			return new Color(0.25f, 0.85f, 0.35f, 1f);
		}
		if (value > 40f)
		{
			return new Color(0.95f, 0.78f, 0.2f, 1f);
		}
		if (value > 15f)
		{
			return new Color(1f, 0.45f, 0.12f, 1f);
		}
		return new Color(0.85f, 0.15f, 0.15f, 1f);
	}

	private static string GetTemperatureLabel(float value)
	{
		if (value > 70f)
		{
			return "Warm";
		}
		if (value > 40f)
		{
			return "Chilly";
		}
		if (value > 15f)
		{
			return "Cold";
		}
		return "Freezing";
	}
}
internal struct SurvivalSnapshot
{
	public readonly bool IsSwimming;

	public readonly bool IsSheltered;

	public readonly bool IsWet;

	public readonly bool IsNearFire;

	public readonly bool IsCold;

	public readonly bool IsFreezing;

	public readonly bool IsNight;

	public readonly bool IsMountain;

	public readonly bool IsDeepNorth;

	public readonly Biome Biome;

	public SurvivalSnapshot(bool isSwimming, bool isSheltered, bool isWet, bool isNearFire, bool isCold, bool isFreezing, bool isNight, bool isMountain, bool isDeepNorth, Biome biome)
	{
		//IL_0046: 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)
		IsSwimming = isSwimming;
		IsSheltered = isSheltered;
		IsWet = isWet;
		IsNearFire = isNearFire;
		IsCold = isCold;
		IsFreezing = isFreezing;
		IsNight = isNight;
		IsMountain = isMountain;
		IsDeepNorth = isDeepNorth;
		Biome = biome;
	}

	public string ToDiagnosticText()
	{
		//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)
		string[] obj = new string[20]
		{
			"biome=",
			((object)Biome/*cast due to .constrained prefix*/).ToString(),
			", swimming=",
			null,
			null,
			null,
			null,
			null,
			null,
			null,
			null,
			null,
			null,
			null,
			null,
			null,
			null,
			null,
			null,
			null
		};
		bool isSwimming = IsSwimming;
		obj[3] = isSwimming.ToString();
		obj[4] = ", sheltered=";
		isSwimming = IsSheltered;
		obj[5] = isSwimming.ToString();
		obj[6] = ", wet=";
		isSwimming = IsWet;
		obj[7] = isSwimming.ToString();
		obj[8] = ", nearFire=";
		isSwimming = IsNearFire;
		obj[9] = isSwimming.ToString();
		obj[10] = ", cold=";
		isSwimming = IsCold;
		obj[11] = isSwimming.ToString();
		obj[12] = ", freezing=";
		isSwimming = IsFreezing;
		obj[13] = isSwimming.ToString();
		obj[14] = ", night=";
		isSwimming = IsNight;
		obj[15] = isSwimming.ToString();
		obj[16] = ", mountain=";
		isSwimming = IsMountain;
		obj[17] = isSwimming.ToString();
		obj[18] = ", deepNorth=";
		isSwimming = IsDeepNorth;
		obj[19] = isSwimming.ToString();
		return string.Concat(obj);
	}
}
internal struct TemperatureSettings
{
	public readonly float SafeRecoveryRate;

	public readonly float NearFireWarmingRate;

	public readonly float WetCoolingRate;

	public readonly float ColdEnvironmentCoolingRate;

	public readonly float FreezingEnvironmentCoolingRate;

	public readonly float MountainCoolingRate;

	public readonly float DeepNorthCoolingRate;

	public readonly float NightCoolingRate;

	public readonly float SwimmingCoolingRate;

	public readonly float ShelterCoolingMultiplier;

	public TemperatureSettings(float safeRecoveryRate, float nearFireWarmingRate, float wetCoolingRate, float coldEnvironmentCoolingRate, float freezingEnvironmentCoolingRate, float mountainCoolingRate, float deepNorthCoolingRate, float nightCoolingRate, float swimmingCoolingRate, float shelterCoolingMultiplier)
	{
		SafeRecoveryRate = safeRecoveryRate;
		NearFireWarmingRate = nearFireWarmingRate;
		WetCoolingRate = wetCoolingRate;
		ColdEnvironmentCoolingRate = coldEnvironmentCoolingRate;
		FreezingEnvironmentCoolingRate = freezingEnvironmentCoolingRate;
		MountainCoolingRate = mountainCoolingRate;
		DeepNorthCoolingRate = deepNorthCoolingRate;
		NightCoolingRate = nightCoolingRate;
		SwimmingCoolingRate = swimmingCoolingRate;
		ShelterCoolingMultiplier = shelterCoolingMultiplier;
	}
}
internal static class TemperatureRules
{
	public static float GetTemperatureRate(SurvivalSnapshot snapshot, TemperatureSettings settings)
	{
		float num = 0f;
		if (snapshot.IsSwimming)
		{
			num += settings.SwimmingCoolingRate;
		}
		else
		{
			if (snapshot.IsWet)
			{
				num += settings.WetCoolingRate;
			}
			if (snapshot.IsFreezing)
			{
				num += settings.FreezingEnvironmentCoolingRate;
			}
			else if (snapshot.IsCold)
			{
				num += settings.ColdEnvironmentCoolingRate;
			}
			if (snapshot.IsMountain)
			{
				num += settings.MountainCoolingRate;
			}
			if (snapshot.IsDeepNorth)
			{
				num += settings.DeepNorthCoolingRate;
			}
			if (snapshot.IsNight)
			{
				num += settings.NightCoolingRate;
			}
		}
		if (snapshot.IsSheltered && num > 0f)
		{
			num *= settings.ShelterCoolingMultiplier;
		}
		if (snapshot.IsNearFire)
		{
			return settings.NearFireWarmingRate - num;
		}
		if (num <= 0f)
		{
			return settings.SafeRecoveryRate;
		}
		return 0f - num;
	}
}