Decompiled source of CreatureDiscomforts v1.0.0

CreatureDiscomforts.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using CreatureDiscomforts.Effects;
using CreatureDiscomforts.Model;
using CreatureDiscomforts.Survey;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using SOD.Common;
using SOD.Common.Helpers;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("CreatureDiscomforts")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CreatureDiscomforts")]
[assembly: AssemblyTitle("CreatureDiscomforts")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.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 CreatureDiscomforts
{
	[BepInPlugin("ekem.creaturediscomforts", "Creature Discomforts", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BasePlugin
	{
		private Harmony? _harmony;

		public static ManualLogSource Log { get; private set; }

		public static Settings Cfg { get; private set; }

		public override void Load()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			Log = ((BasePlugin)this).Log;
			Cfg = new Settings(((BasePlugin)this).Config);
			_harmony = new Harmony("ekem.creaturediscomforts");
			_harmony.PatchAll();
			InstallHotkeys();
			Illness.Install();
			ManualLogSource log = Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(9, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Creature Discomforts");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.0");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded.");
			}
			log.LogInfo(val);
		}

		private static void InstallHotkeys()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			ClassInjector.RegisterTypeInIl2Cpp<Heartbeat>();
			GameObject val = new GameObject("Creature DiscomfortsHotkeys");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)61;
			val.AddComponent<Heartbeat>();
		}
	}
	public class Settings
	{
		public readonly ConfigEntry<float> ThirstToHunger;

		public readonly ConfigEntry<bool> Starving;

		public readonly ConfigEntry<float> StarvingBelow;

		public readonly ConfigEntry<float> StarvingDamage;

		public readonly ConfigEntry<bool> Parched;

		public readonly ConfigEntry<float> ParchedBelow;

		public readonly ConfigEntry<float> ParchedDamage;

		public readonly ConfigEntry<float> HealthFloor;

		public readonly ConfigEntry<float> StumbleChance;

		public readonly ConfigEntry<float> ThirstHeadachePerHour;

		public readonly ConfigEntry<bool> CatchingColds;

		public readonly ConfigEntry<float> ColdThreshold;

		public readonly ConfigEntry<float> CatchFromCold;

		public readonly ConfigEntry<float> CatchFromWet;

		public readonly ConfigEntry<float> CatchFromBoth;

		public readonly ConfigEntry<float> RecoveryPerHour;

		public readonly ConfigEntry<float> RecoverAboveHeat;

		public readonly ConfigEntry<float> SleepRecovery;

		public readonly ConfigEntry<bool> Immunity;

		public readonly ConfigEntry<float> ImmunityLossPerHour;

		public readonly ConfigEntry<float> ImmunityLossStarving;

		public readonly ConfigEntry<float> ImmunityGainPerHour;

		public readonly ConfigEntry<float> ImmunityBaseGain;

		public readonly ConfigEntry<float> LowImmunityCatch;

		public readonly ConfigEntry<float> LowImmunityRecovery;

		public readonly ConfigEntry<float> AlcoholHeatLoss;

		public readonly ConfigEntry<bool> RealisticDrinks;

		public readonly ConfigEntry<float> StrongDrinkThirst;

		public readonly ConfigEntry<float> StrongDrinkTiring;

		public readonly ConfigEntry<float> NauseaFromDrunk;

		public readonly ConfigEntry<float> DrunkNauseaPerHour;

		public readonly ConfigEntry<float> OverdrinkNausea;

		public readonly ConfigEntry<float> RetchAbove;

		public readonly ConfigEntry<float> RetchPerHour;

		public readonly ConfigEntry<float> VomitSobers;

		public readonly ConfigEntry<float> VomitTiring;

		public readonly ConfigEntry<bool> DebugLogging;

		public readonly ConfigEntry<KeyCode> SurveyKey;

		public readonly ConfigEntry<KeyCode> OverlayKey;

		public readonly ConfigEntry<KeyCode> ShopKey;

		public readonly ConfigEntry<KeyCode> IllnessKey;

		public readonly ConfigEntry<KeyCode> MoneyKey;

		public Settings(ConfigFile config)
		{
			ThirstToHunger = config.Bind<float>("Needs", "ThirstToHunger", 1.5f, "How fast thirst drains compared to hunger. 1.5 means you get thirsty 1.5 times as fast as you get hungry. 0 keeps the game's own rate.");
			Starving = config.Bind<bool>("Needs", "Starving", true, "Running out of food entirely makes you Starving: no health recovery, unsteady on your feet, and slowly losing health. Never down to a hospital visit, see HealthFloor.");
			StarvingBelow = config.Bind<float>("Needs", "StarvingBelow", 0.02f, "At or below this nourishment (0..1) you are starving. The game's own Hungry starts at 0.2.");
			StarvingDamage = config.Bind<float>("Needs", "StarvingDamage", 0.1f, "How much health you lose per game hour while starving, as a share of your maximum health. 0 turns the damage off.");
			Parched = config.Bind<bool>("Needs", "Parched", true, "Running out of water entirely makes you Parched: the same as Starving, a little harsher.");
			ParchedBelow = config.Bind<float>("Needs", "ParchedBelow", 0.02f, "At or below this hydration (0..1) you are parched. The game's own Thirsty starts at 0.2.");
			ParchedDamage = config.Bind<float>("Needs", "ParchedDamage", 0.15f, "How much health you lose per game hour while parched, as a share of your maximum health. 0 turns the damage off.");
			HealthFloor = config.Bind<float>("Needs", "HealthFloor", 0.25f, "Starving and parched never take your health below this share of the maximum, and neither do stumbles while you are starving or parched.");
			StumbleChance = config.Bind<float>("Needs", "StumbleChance", 0.25f, "How often you stumble and fall while starving or parched, compared to being as drunk as you can get (1 = just as often, about one step in fifty). Both at once add up. 0 turns this off. Takes effect after restarting the game.");
			ThirstHeadachePerHour = config.Bind<float>("Needs", "ThirstHeadachePerHour", 0.8f, "While you are Thirsty, a headache builds up this much per game hour. The game eases a headache by about 0.5-0.75 per hour, so it creeps in slowly. Painkillers stop it for a while. 0 turns this off.");
			CatchingColds = config.Bind<bool>("Illness", "CatchingColds", true, "Being out in the cold or soaking wet can give you a cold, with a stuffy nose, a headache, fever and chills.");
			ColdThreshold = config.Bind<float>("Illness", "ColdThreshold", 0.25f, "Below this body heat (0..1) you count as freezing.");
			CatchFromCold = config.Bind<float>("Illness", "CatchFromCold", 0.1f, "How much of a cold you pick up per game hour when completely frozen but dry.");
			CatchFromWet = config.Bind<float>("Illness", "CatchFromWet", 0.05f, "How much of a cold you pick up per game hour when soaked but warm.");
			CatchFromBoth = config.Bind<float>("Illness", "CatchFromBoth", 0.1f, "Extra per game hour on top of the two above when you are frozen AND soaked. With the defaults that makes 0.25: fever in about two hours.");
			RecoveryPerHour = config.Bind<float>("Illness", "RecoveryPerHour", 0.03f, "How fast a cold wears off per game hour while you are warm and dry and awake. At 0.03 a bad cold takes about a day to pass.");
			RecoverAboveHeat = config.Bind<float>("Illness", "RecoverAboveHeat", 0.5f, "A cold only wears off when your body heat is at least this. Between this and ColdThreshold it neither gets worse nor better.");
			SleepRecovery = config.Bind<float>("Illness", "SleepRecovery", 3f, "How many times faster a cold wears off while you sleep in a bed.");
			Immunity = config.Bind<bool>("Illness", "Immunity", true, "Going hungry, thirsty or without sleep wears down your resistance, and eating, drinking and sleeping well build it back up. It is never shown: you only notice it in how easily you catch a cold and how long it takes to pass.");
			ImmunityLossPerHour = config.Bind<float>("Illness", "ImmunityLossPerHour", 0.01f, "How much resistance (0..1) you lose per game hour for each of Hungry, Thirsty and Tired.");
			ImmunityLossStarving = config.Bind<float>("Illness", "ImmunityLossStarving", 0.01f, "Extra resistance lost per game hour for each of Starving and Parched. With the defaults, a whole day without food or water takes it from full to about 0.4.");
			ImmunityGainPerHour = config.Bind<float>("Illness", "ImmunityGainPerHour", 0.05f, "Resistance regained per game hour for each of Energized, Hydrated and Well Rested.");
			ImmunityBaseGain = config.Bind<float>("Illness", "ImmunityBaseGain", 0.015f, "Resistance regained per game hour while you are neither hungry, thirsty nor tired.");
			LowImmunityCatch = config.Bind<float>("Illness", "LowImmunityCatch", 2f, "How many times faster you catch a cold with no resistance left. In between it scales evenly; 1 means resistance doesn't affect catching a cold.");
			LowImmunityRecovery = config.Bind<float>("Illness", "LowImmunityRecovery", 0.5f, "How fast a cold wears off with no resistance left, compared to full resistance (0.5 = half as fast). 1 means resistance doesn't affect getting better.");
			AlcoholHeatLoss = config.Bind<float>("Alcohol", "AlcoholHeatLoss", 0.5f, "While drunk you lose body heat this much faster (0.5 = one and a half times), and you don't feel the cold: no shivering, no chills. 0 turns this off. Takes effect after restarting the game.");
			RealisticDrinks = config.Bind<bool>("Alcohol", "RealisticDrinks", true, "Spirits dry you out instead of quenching thirst, and coffee or tea no longer sober you up or cancel painkillers. Takes effect after restarting the game.");
			StrongDrinkThirst = config.Bind<float>("Alcohol", "StrongDrinkThirst", 0.3f, "How much thirst a glass of spirits (bourbon, vodka) costs instead of quenching it. Beer, cider and wine are unchanged. Takes effect after restarting the game.");
			StrongDrinkTiring = config.Bind<float>("Alcohol", "StrongDrinkTiring", 0.15f, "How much energy a glass of spirits costs. Takes effect after restarting the game.");
			NauseaFromDrunk = config.Bind<float>("Alcohol", "NauseaFromDrunk", 0.7f, "Above this drunkenness (0..1) you start feeling sick. 0 turns this off.");
			DrunkNauseaPerHour = config.Bind<float>("Alcohol", "DrunkNauseaPerHour", 1.5f, "How fast nausea builds per game hour when completely drunk. The game eases nausea on its own, so a little over the line passes and a lot does not.");
			OverdrinkNausea = config.Bind<float>("Alcohol", "OverdrinkNausea", 0.5f, "Once you are as drunk as you can get, whatever more you drink turns into nausea instead: this much per unit of drunkenness that doesn't fit. A second bottle of vodka will come back up. 0 turns this off.");
			RetchAbove = config.Bind<float>("Needs", "RetchAbove", 0.8f, "Above this nausea (0..1) you may throw up wherever you are, not just over a toilet.");
			RetchPerHour = config.Bind<float>("Needs", "RetchPerHour", 12f, "How likely that is per game hour at full nausea (12 = usually within five minutes). Less likely when only just past RetchAbove. 0 turns this off.");
			VomitSobers = config.Bind<float>("Alcohol", "VomitSobers", 0.6f, "How much a full throw-up sobers you. 0 turns this off.");
			VomitTiring = config.Bind<float>("Needs", "VomitTiring", 0.15f, "How much energy throwing up costs. 0 turns this off.");
			DebugLogging = config.Bind<bool>("Debug", "DebugLogging", false, "Logs every change to your own condition, and what the game has switched on.");
			SurveyKey = config.Bind<KeyCode>("Debug", "SurveyKey", (KeyCode)288, "Logs which survival statuses the game has enabled and how you are doing right now.");
			OverlayKey = config.Bind<KeyCode>("Debug", "OverlayKey", (KeyCode)289, "Toggles an on-screen panel with your current needs and how fast they change per game hour.");
			ShopKey = config.Bind<KeyCode>("Debug", "ShopKey", (KeyCode)290, "Logs every item sold in shops and what it does to your needs, and writes the same as a table to BepInEx/CreatureDiscomforts-shop.tsv.");
			IllnessKey = config.Bind<KeyCode>("Debug", "IllnessKey", (KeyCode)0, "Makes your cold 0.2 worse each press; past the worst it cures you. For testing; unbound by default (F10 is handy).");
			MoneyKey = config.Bind<KeyCode>("Debug", "MoneyKey", (KeyCode)0, "Gives you 10000 money. For testing; unbound by default (F11 is handy).");
		}
	}
	public static class PluginInfo
	{
		public const string Guid = "ekem.creaturediscomforts";

		public const string Name = "Creature Discomforts";

		public const string Version = "1.0.0";
	}
}
namespace CreatureDiscomforts.Survey
{
	public static class IconDump
	{
		public static void Run()
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			string text = Path.Combine(Paths.BepInExRootPath, "CreatureDiscomforts-icons");
			Directory.CreateDirectory(text);
			int num = 0;
			bool flag = default(bool);
			foreach (Object item in (Il2CppArrayBase<Object>)(object)Resources.FindObjectsOfTypeAll(Il2CppType.Of<StatusPreset>()))
			{
				StatusPreset val = ((Il2CppObjectBase)item).TryCast<StatusPreset>();
				if ((Object)(object)((val != null) ? val.icon : null) == (Object)null)
				{
					continue;
				}
				try
				{
					File.WriteAllBytes(Path.Combine(text, ((Object)val).name + ".png"), Encode(val.icon));
					num++;
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(16, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[status] icon ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)val).name);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
					}
					log.LogWarning(val2);
				}
			}
			ManualLogSource log2 = Plugin.Log;
			BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(34, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[status] ");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" status icons written to ");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text);
			}
			log2.LogInfo(val3);
		}

		private static byte[] Encode(Sprite sprite)
		{
			//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_0047: 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_004d: 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_0060: Expected O, but got Unknown
			Texture2D texture = sprite.texture;
			Rect textureRect = sprite.textureRect;
			RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0);
			RenderTexture active = RenderTexture.active;
			try
			{
				Graphics.Blit((Texture)(object)texture, temporary);
				RenderTexture.active = temporary;
				Texture2D val = new Texture2D((int)((Rect)(ref textureRect)).width, (int)((Rect)(ref textureRect)).height, (TextureFormat)4, false);
				val.ReadPixels(textureRect, 0, 0);
				val.Apply();
				return Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)ImageConversion.EncodeToPNG(val));
			}
			finally
			{
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
			}
		}
	}
	public static class SelfSurvey
	{
		public static void Run()
		{
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Expected O, but got Unknown
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Expected O, but got Unknown
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Expected O, but got Unknown
			Game instance = Game.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[me] no game instance");
				return;
			}
			List<string> on = new List<string>();
			List<string> off = new List<string>();
			Check("cold", instance.coldStatusEnabled);
			Check("smelly", instance.smellyStatusEnabled);
			Check("headache", instance.headacheStatusEnabled);
			Check("injury", instance.injuryStatusEnabled);
			Check("tired", instance.tiredStatusEnabled);
			Check("hunger", instance.hungerStatusEnabled);
			Check("hydration", instance.hydrationStatusEnabled);
			Check("numb", instance.numbStatusEnabled);
			Check("bleeding", instance.bleedingStatusEnabled);
			Check("wet", instance.wetStatusEnabled);
			Check("sick", instance.sickStatusEnabled);
			Check("drunk", instance.drunkStatusEnabled);
			Check("starch addiction", instance.starchAddictionEnabled);
			Check("poison", instance.poisonStatusEnabled);
			Check("blinded", instance.blindedStatusEnabled);
			Check("energized", instance.energizedStatusEnabled);
			Check("hydrated", instance.hydratedStatusEnabled);
			Check("focused", instance.focusedStatusEnabled);
			Check("well rested", instance.wellRestedStatusEnabled);
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(22, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] statuses ON  (");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(on.Count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(", ", on));
			}
			log.LogInfo(val);
			ManualLogSource log2 = Plugin.Log;
			val = new BepInExInfoLogInterpolatedStringHandler(22, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] statuses OFF (");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(off.Count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(", ", off));
			}
			log2.LogInfo(val);
			Player instance2 = Player.Instance;
			Human val2 = ((instance2 != null) ? ((Il2CppObjectBase)instance2).TryCast<Human>() : null);
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogInfo((object)"[me] no player to read");
				return;
			}
			ManualLogSource log3 = Plugin.Log;
			val = new BepInExInfoLogInterpolatedStringHandler(52, 6, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] food ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.nourishment, "F2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", water ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.hydration, "F2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("energy ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.energy, "F2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", alert ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.alertness, "F2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("hygiene ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.hygiene, "F2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", heat ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.heat, "F2");
			}
			log3.LogInfo(val);
			ManualLogSource log4 = Plugin.Log;
			val = new BepInExInfoLogInterpolatedStringHandler(44, 5, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] sick ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.sick, "F2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", wet ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.wet, "F2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", drunk ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.drunk, "F2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("headache ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.headache, "F2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", health ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(((Actor)val2).currentHealth, "F2");
			}
			log4.LogInfo(val);
			StatusEffects();
			IconDump.Run();
			void Check(string name, bool enabled)
			{
				(enabled ? on : off).Add(name);
			}
		}

		private static void StatusEffects()
		{
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Expected O, but got Unknown
			StatusController instance = StatusController.Instance;
			HashSet<StatusPreset> val = ((instance != null) ? instance.activeStatuses : null);
			bool flag2 = default(bool);
			foreach (StatusPreset item in from o in (IEnumerable<Object>)Resources.FindObjectsOfTypeAll(Il2CppType.Of<StatusPreset>())
				select ((Il2CppObjectBase)o).TryCast<StatusPreset>() into p
				where (SoCustomComparison)(object)p != (SoCustomComparison)null
				orderby ((Object)p).name
				select p)
			{
				List<string> parts = new List<string>();
				Flag("stopsRecovery", item.stopsRecovery);
				Flag("stopsSprint", item.stopsSprint);
				Flag("stopsJump", item.stopsJump);
				Num("recovery", item.recoveryRatePlusMP);
				Num("maxHealth", item.maxHealthPlusMP);
				Num("speed", item.movementSpeedPlusMP);
				Num("tempGain", item.temperatureGainPlusMP);
				Num("dmgIn", item.damageIncomingPlusMP);
				Num("dmgOut", item.damageOutgoingPlusMP);
				Num("drunkControls", item.drunkControls);
				Num("tripWet", item.tripChanceWet);
				Num("tripDrunk", item.tripChanceDrunk);
				Num("drunkVision", item.drunkVision);
				Num("shiver", item.shiverVision);
				Num("headacheVision", item.headacheVision);
				Num("lens", item.drunkLensDistort);
				Num("headBob", item.affectHeadBob);
				Num("bloom", item.bloomIntensityPlusMP);
				Num("blur", item.motionBlurPlusMP);
				Num("chromatic", item.chromaticAbberationAmount);
				Num("vignette", item.vignetteAmount);
				Num("exposure", item.expsosure);
				Flag("channelMixer", item.useChannelMixer);
				bool flag = val?.Contains(item) ?? false;
				string text = ((parts.Count == 0) ? "(nothing)" : string.Join(", ", parts));
				ManualLogSource log = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(11, 3, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[status] ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(flag ? "*" : " ");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)item).name.PadRight(22));
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text);
				}
				log.LogInfo(val2);
				void Flag(string name, bool on)
				{
					if (on)
					{
						parts.Add(name);
					}
				}
				void Num(string name, float v)
				{
					if (v != 0f)
					{
						parts.Add($"{name} {v:+0.##;-0.##}");
					}
				}
			}
		}
	}
	public static class ShopSurvey
	{
		private static readonly (string Name, Func<RetailItemPreset, float> Read)[] Effects = new(string, Func<RetailItemPreset, float>)[24]
		{
			("nourishment", (RetailItemPreset r) => r.nourishment),
			("hydration", (RetailItemPreset r) => r.hydration),
			("alertness", (RetailItemPreset r) => r.alertness),
			("energy", (RetailItemPreset r) => r.energy),
			("wellRested", (RetailItemPreset r) => r.wellRested),
			("excitement", (RetailItemPreset r) => r.excitement),
			("chores", (RetailItemPreset r) => r.chores),
			("hygiene", (RetailItemPreset r) => r.hygiene),
			("bladder", (RetailItemPreset r) => r.bladder),
			("heat", (RetailItemPreset r) => r.heat),
			("wet", (RetailItemPreset r) => r.wet),
			("drunk", (RetailItemPreset r) => r.drunk),
			("sick", (RetailItemPreset r) => r.sick),
			("headache", (RetailItemPreset r) => r.headache),
			("starchAddiction", (RetailItemPreset r) => r.starchAddiction),
			("poisoned", (RetailItemPreset r) => r.poisoned),
			("numb", (RetailItemPreset r) => r.numb),
			("bleeding", (RetailItemPreset r) => r.bleeding),
			("bruised", (RetailItemPreset r) => r.bruised),
			("blackEye", (RetailItemPreset r) => r.blackEye),
			("brokenLeg", (RetailItemPreset r) => r.brokenLeg),
			("blackedOut", (RetailItemPreset r) => r.blackedOut),
			("breath", (RetailItemPreset r) => r.breath),
			("health", (RetailItemPreset r) => r.health)
		};

		private const int ShownSellers = 5;

		private static Dictionary<string, List<string>> Sellers()
		{
			Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>();
			CityData instance = CityData.Instance;
			List<Company> val = ((instance != null) ? instance.companyDirectory : null);
			if (val == null)
			{
				return dictionary;
			}
			Enumerator<Company> enumerator = val.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Company current = enumerator.Current;
				if (((current != null) ? current.prices : null) == null)
				{
					continue;
				}
				NewAddress address = current.address;
				string text = ((address != null) ? ((Object)address).name : null);
				string value = ((text != null && text.Length > 0 && text != current.name) ? (current.name + " (" + text + ")") : current.name);
				Enumerator<InteractablePreset, int> enumerator2 = current.prices.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					KeyValuePair<InteractablePreset, int> current2 = enumerator2.Current;
					InteractablePreset key = current2.Key;
					string key2 = ((key != null) ? ((SoCustomComparison)key).presetName : null) ?? "";
					if (!dictionary.TryGetValue(key2, out var value2))
					{
						value2 = (dictionary[key2] = new List<string>());
					}
					value2.Add($"{value} cr{current2.Value}");
				}
			}
			return dictionary;
		}

		public static void Run()
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Expected O, but got Unknown
			//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ab: Expected O, but got Unknown
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			Toolbox instance = Toolbox.Instance;
			Dictionary<string, InteractablePreset> val = ((instance != null) ? instance.objectPresetDictionary : null);
			if (val == null)
			{
				Plugin.Log.LogWarning((object)"[shop] no preset dictionary yet");
				return;
			}
			Dictionary<string, List<string>> dictionary = Sellers();
			List<(string, string, string, string)> list = new List<(string, string, string, string)>();
			Enumerator<string, InteractablePreset> enumerator = val.GetEnumerator();
			bool isConsumable = default(bool);
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, InteractablePreset> current = enumerator.Current;
				InteractablePreset value = current.Value;
				RetailItemPreset retail = ((value != null) ? value.retailItem : null);
				if (!((SoCustomComparison)(object)retail == (SoCustomComparison)null))
				{
					List<(string, float)> list2 = (from e in Effects
						select (Name: e.Name, Value: e.Read(retail)) into e
						where e.Value != 0f
						select e).ToList();
					string text = ((object)retail.menuCategory/*cast due to .constrained prefix*/).ToString();
					string value2 = ((value.value.x == value.value.y) ? $"{value.value.x:0}" : $"{value.value.x:0}-{value.value.y:0}");
					string value3 = (string.IsNullOrEmpty(retail.brandName) ? "" : (" [" + retail.brandName + "]"));
					string value4 = ((list2.Count == 0) ? "(no effect)" : string.Join(", ", list2.Select<(string, float), string>(((string Name, float Value) e) => $"{e.Name} {e.Value:+0.##;-0.##}")));
					dictionary.TryGetValue(((SoCustomComparison)value).presetName ?? "", out var value5);
					if (value5 == null)
					{
						value5 = new List<string>();
					}
					string value6 = ((value5.Count == 0) ? "not sold" : ($"{value5.Count} shops: " + string.Join("; ", value5.Take(5)) + ((value5.Count > 5) ? "; ..." : "")));
					string key = current.Key;
					string item = $"[shop] {text,-10} {current.Key}{value3}  cr{value2}  {value4}\n[shop]            at {value6}";
					string[] obj = new string[9]
					{
						text,
						current.Key,
						retail.brandName ?? "",
						value.value.x.ToString("0"),
						value.value.y.ToString("0"),
						null,
						null,
						null,
						null
					};
					isConsumable = retail.isConsumable;
					obj[5] = isConsumable.ToString();
					obj[6] = value.consumableAmount.ToString("0.##");
					obj[7] = value5.Count.ToString();
					obj[8] = string.Join("; ", value5);
					list.Add((text, key, item, string.Join("\t", obj.Concat(Effects.Select(((string Name, Func<RetailItemPreset, float> Read) e) => e.Read(retail).ToString("0.###"))))));
				}
			}
			list.Sort(delegate((string Category, string Name, string Line, string Tsv) a, (string Category, string Name, string Line, string Tsv) b)
			{
				int num = string.CompareOrdinal(a.Category, b.Category);
				return (num == 0) ? string.CompareOrdinal(a.Name, b.Name) : num;
			});
			foreach (var item2 in list)
			{
				Plugin.Log.LogInfo((object)item2.Item3);
			}
			ManualLogSource log = Plugin.Log;
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref isConsumable);
			if (isConsumable)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[shop] ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(list.Count);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" retail items");
			}
			log.LogInfo(val2);
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine(string.Join("\t", new string[9] { "category", "preset", "brand", "priceMin", "priceMax", "consumable", "amount", "shops", "soldAt" }.Concat(Effects.Select(((string Name, Func<RetailItemPreset, float> Read) e) => e.Name))));
			foreach (var item3 in list)
			{
				stringBuilder.AppendLine(item3.Item4);
			}
			string text2 = Path.Combine(Paths.BepInExRootPath, "CreatureDiscomforts-shop.tsv");
			File.WriteAllText(text2, stringBuilder.ToString());
			ManualLogSource log2 = Plugin.Log;
			val2 = new BepInExInfoLogInterpolatedStringHandler(16, 1, ref isConsumable);
			if (isConsumable)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[shop] table -> ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text2);
			}
			log2.LogInfo(val2);
		}
	}
}
namespace CreatureDiscomforts.Model
{
	public static class Illness
	{
		private sealed class Saved
		{
			public float Illness { get; set; }

			public float? Immunity { get; set; }

			public Dictionary<string, float>? Relieved { get; set; }

			public Dictionary<string, List<float>>? Doses { get; set; }
		}

		private const string FileName = "creaturediscomforts.json";

		private const float MaxStep = 1f;

		private static float _lastGameTime = float.NaN;

		private static float _nextReport = float.NaN;

		public static float Level { get; private set; }

		public static void Install()
		{
			Lib.SaveGame.OnBeforeSave += OnBeforeSave;
			Lib.SaveGame.OnAfterLoad += OnAfterLoad;
			Lib.SaveGame.OnBeforeNewGame += delegate
			{
				Reset(0f);
				Remedies.Load(null, null);
			};
			Lib.SaveGame.OnBeforeDelete += OnBeforeDelete;
		}

		public static float Coldness(Human player)
		{
			float value = Plugin.Cfg.ColdThreshold.Value;
			if (!(value <= 0f))
			{
				return Mathf.Clamp01(1f - player.heat / value);
			}
			return 0f;
		}

		private static bool Asleep()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			InteractionController instance = InteractionController.Instance;
			Interactable val = ((instance != null) ? instance.lockedInInteraction : null);
			if ((SoCustomComparison)(object)((val != null) ? val.preset : null) != (SoCustomComparison)null)
			{
				return (int)val.preset.specialCaseFlag == 1;
			}
			return false;
		}

		public static void Tick()
		{
			SessionData instance = SessionData.Instance;
			Player instance2 = Player.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null)
			{
				_lastGameTime = float.NaN;
				return;
			}
			float gameTime = instance.gameTime;
			float num = (float.IsNaN(_lastGameTime) ? 0f : (gameTime - _lastGameTime));
			_lastGameTime = gameTime;
			if (num < 0f || num > 1f)
			{
				num = 0f;
			}
			Starvation.Apply(instance2, num);
			Immunity.Tick(instance2, num);
			if (!Plugin.Cfg.CatchingColds.Value)
			{
				Level = 0f;
			}
			else if (num > 0f)
			{
				float num2 = Coldness((Human)(object)instance2);
				float num3 = Mathf.Clamp01(((Human)instance2).wet);
				float num4 = Plugin.Cfg.CatchFromCold.Value * num2 + Plugin.Cfg.CatchFromWet.Value * num3 + Plugin.Cfg.CatchFromBoth.Value * num2 * num3;
				num4 *= Immunity.CatchMultiplier;
				if (num4 > 0f)
				{
					Level = Mathf.Clamp01(Level + num4 * num);
				}
				else if (((Human)instance2).heat >= Plugin.Cfg.RecoverAboveHeat.Value)
				{
					Level = Mathf.Clamp01(Level - Plugin.Cfg.RecoveryPerHour.Value * num * (Asleep() ? Plugin.Cfg.SleepRecovery.Value : 1f) * Immunity.RecoveryMultiplier);
				}
			}
			Symptoms.Apply(instance2, Level, num);
			Hourly(instance2, gameTime);
		}

		private static void Hourly(Player player, float now)
		{
			if (Plugin.Cfg.DebugLogging.Value && (float.IsNaN(_nextReport) || !(now < _nextReport) || !(now > _nextReport - 2f)))
			{
				_nextReport = Mathf.Floor(now) + 1f;
				StatusController instance = StatusController.Instance;
				Plugin.Log.LogInfo((object)($"[me] hourly {now:F1}h: illness {Level:F2}, immunity {Immunity.Level:F2}, heat {((Human)player).heat:F2}, wet {((Human)player).wet:F2}, health {((Actor)player).currentHealth:F2}/{((Actor)player).maximumHealth:F2}, drunk {((Human)player).drunk:F2}, food {((Human)player).nourishment:F2}, water {((Human)player).hydration:F2}, energy {((Human)player).energy:F2}, sick {((Human)player).sick:F2}, heat loss x{((instance != null) ? instance.temperatureGainMultiplier : 1f):F2}, recovery {(((Object)(object)instance != (Object)null && instance.disabledRecovery) ? "off" : "on")}" + (Asleep() ? ", asleep" : "")));
			}
		}

		public static void DebugBump()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			Level = ((Level >= 0.99f) ? 0f : Mathf.Clamp01(Level + 0.2f));
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] illness set to ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(Level, "F2");
			}
			log.LogInfo(val);
		}

		private static void Reset(float level)
		{
			Level = level;
			_lastGameTime = float.NaN;
			Immunity.Reset(1f);
		}

		private static string PathFor(SaveGameArgs args)
		{
			return Lib.SaveGame.GetSaveGameDataPath(args, "creaturediscomforts.json");
		}

		private static void OnBeforeSave(object? sender, SaveGameArgs e)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			try
			{
				File.WriteAllText(PathFor(e), JsonSerializer.Serialize(new Saved
				{
					Illness = Level,
					Immunity = Immunity.Level,
					Relieved = Remedies.SaveRelief(),
					Doses = Remedies.SaveDoses()
				}));
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(21, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] failed to save: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogError(val);
			}
		}

		private static void OnAfterLoad(object? sender, SaveGameArgs e)
		{
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			Reset(0f);
			Remedies.Load(null, null);
			string path = PathFor(e);
			if (!File.Exists(path))
			{
				return;
			}
			bool flag = default(bool);
			try
			{
				Saved saved = JsonSerializer.Deserialize<Saved>(File.ReadAllText(path));
				Reset(Mathf.Clamp01(saved?.Illness ?? 0f));
				Immunity.Reset(saved?.Immunity ?? 1f);
				Remedies.Load(saved?.Relieved, saved?.Doses);
				ManualLogSource log = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(31, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] loaded illness ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(Level, "F2");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", immunity ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(Immunity.Level, "F2");
				}
				log.LogInfo(val);
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(45, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[me] unreadable save data, starting healthy: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log2.LogError(val2);
			}
		}

		private static void OnBeforeDelete(object? sender, SaveGameArgs e)
		{
			string path = PathFor(e);
			if (File.Exists(path))
			{
				File.Delete(path);
			}
		}
	}
	public static class Immunity
	{
		private const float Low = 0.2f;

		private const float High = 0.9f;

		public static float Level { get; private set; } = 1f;

		public static float CatchMultiplier
		{
			get
			{
				if (!Plugin.Cfg.Immunity.Value)
				{
					return 1f;
				}
				return Mathf.Lerp(Mathf.Max(1f, Plugin.Cfg.LowImmunityCatch.Value), 1f, Level);
			}
		}

		public static float RecoveryMultiplier
		{
			get
			{
				if (!Plugin.Cfg.Immunity.Value)
				{
					return 1f;
				}
				return Mathf.Lerp(Mathf.Clamp01(Plugin.Cfg.LowImmunityRecovery.Value), 1f, Level);
			}
		}

		public static void Reset(float level)
		{
			Level = Mathf.Clamp01(level);
		}

		public static void Tick(Player player, float dt)
		{
			Settings cfg = Plugin.Cfg;
			if (!cfg.Immunity.Value)
			{
				Level = 1f;
			}
			else
			{
				if (dt <= 0f || ((Actor)player).isDead || player.playerKOInProgress)
				{
					return;
				}
				Game instance = Game.Instance;
				if (!((Object)(object)instance == (Object)null))
				{
					int num = ((instance.hungerStatusEnabled && ((Human)player).nourishment <= 0.2f) ? 1 : 0) + ((instance.hydrationStatusEnabled && ((Human)player).hydration <= 0.2f) ? 1 : 0) + ((instance.tiredStatusEnabled && ((Human)player).energy <= 0.2f) ? 1 : 0);
					int num2 = (Starvation.IsStarving ? 1 : 0) + (Starvation.IsParched ? 1 : 0);
					float num3 = (float)(((instance.energizedStatusEnabled && ((Human)player).nourishment >= 0.9f) ? 1 : 0) + ((instance.hydratedStatusEnabled && ((Human)player).hydration >= 0.9f) ? 1 : 0) + ((instance.wellRestedStatusEnabled && ((Human)player).wellRested > 0f) ? 1 : 0)) * cfg.ImmunityGainPerHour.Value - (float)num * cfg.ImmunityLossPerHour.Value - (float)num2 * cfg.ImmunityLossStarving.Value;
					if (num == 0)
					{
						num3 += cfg.ImmunityBaseGain.Value;
					}
					Level = Mathf.Clamp01(Level + num3 * dt);
				}
			}
		}
	}
}
namespace CreatureDiscomforts.Effects
{
	public static class Booze
	{
		private static StatusPreset? _drunk;

		private static StatusPreset? _cold;

		private static float _coldShiver;

		private static bool _ready;

		public static bool NumbToCold { get; private set; }

		public static void Tick()
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			float value = Plugin.Cfg.AlcoholHeatLoss.Value;
			if (value <= 0f || (!_ready && !Setup(value)))
			{
				return;
			}
			StatusController instance = StatusController.Instance;
			HashSet<StatusPreset> val = ((instance != null) ? instance.activeStatuses : null);
			bool flag = val != null && (SoCustomComparison)(object)_drunk != (SoCustomComparison)null && val.Contains(_drunk);
			if (flag != NumbToCold)
			{
				NumbToCold = flag;
				if ((SoCustomComparison)(object)_cold != (SoCustomComparison)null)
				{
					_cold.shiverVision = (flag ? 0f : _coldShiver);
				}
				StatusController instance2 = StatusController.Instance;
				if (instance2 != null)
				{
					instance2.ForceStatusCheck();
				}
				ManualLogSource log = Plugin.Log;
				bool flag2 = default(bool);
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(18, 2, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[me] ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(flag ? "drunk: cold numbed" : "sober: feel the cold again");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", ");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("heat loss x");
					StatusController instance3 = StatusController.Instance;
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>((instance3 != null) ? instance3.temperatureGainMultiplier : 1f, "F2");
				}
				log.LogInfo(val2);
			}
		}

		private static bool Setup(float heatLoss)
		{
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Expected O, but got Unknown
			Toolbox instance = Toolbox.Instance;
			List<StatusPreset> val = ((instance != null) ? instance.allStatuses : null);
			if (val == null)
			{
				return false;
			}
			Enumerator<StatusPreset> enumerator = val.GetEnumerator();
			while (enumerator.MoveNext())
			{
				StatusPreset current = enumerator.Current;
				if (!((SoCustomComparison)(object)current == (SoCustomComparison)null))
				{
					if (((Object)current).name == "Drunk")
					{
						_drunk = current;
					}
					else if (((Object)current).name == "Cold")
					{
						_cold = current;
					}
				}
			}
			if ((SoCustomComparison)(object)_drunk == (SoCustomComparison)null)
			{
				Plugin.Log.LogWarning((object)"[me] no Drunk status, alcohol will not affect the cold");
				_ready = true;
				return false;
			}
			StatusPreset? drunk = _drunk;
			drunk.temperatureGainPlusMP += heatLoss;
			if ((SoCustomComparison)(object)_cold != (SoCustomComparison)null)
			{
				_coldShiver = _cold.shiverVision;
			}
			bool flag = default(bool);
			try
			{
				string text = Lib.DdsStrings.Get("ui.states", "drunk_description") ?? "";
				Lib.DdsStrings.AddOrUpdate("ui.states", "drunk_description", text.TrimEnd() + " You won't feel the cold, but you lose body heat faster.");
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(45, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[me] could not extend the drunk description: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val2);
			}
			ManualLogSource log2 = Plugin.Log;
			BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[me] alcohol: heat loss +");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(heatLoss);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" while drunk");
			}
			log2.LogInfo(val3);
			_ready = true;
			return true;
		}
	}
	public class Heartbeat : MonoBehaviour
	{
		public Heartbeat(IntPtr pointer)
			: base(pointer)
		{
		}

		[HideFromIl2Cpp]
		private static bool Pressed(ConfigEntry<KeyCode> key)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if ((int)key.Value != 0)
			{
				return Input.GetKeyDown(key.Value);
			}
			return false;
		}

		private void Update()
		{
			if (Pressed(Plugin.Cfg.SurveyKey))
			{
				Plugin.Log.LogInfo((object)"[hotkey] self survey");
				SelfSurvey.Run();
			}
			if (Pressed(Plugin.Cfg.ShopKey))
			{
				Plugin.Log.LogInfo((object)"[hotkey] shop survey");
				ShopSurvey.Run();
			}
			if (Pressed(Plugin.Cfg.IllnessKey))
			{
				Illness.DebugBump();
			}
			if (Pressed(Plugin.Cfg.MoneyKey) && (Object)(object)GameplayController.Instance != (Object)null)
			{
				GameplayController.Instance.AddMoney(10000, true, "debug");
				Plugin.Log.LogInfo((object)"[hotkey] +10000 money");
			}
			if (Pressed(Plugin.Cfg.OverlayKey))
			{
				NeedsOverlay.Toggle();
			}
			NeedsOverlay.Tick();
			Thirst.Apply();
			Shelf.Apply();
			Stomach.Tick();
			Booze.Tick();
			Illness.Tick();
		}

		private void OnGUI()
		{
			NeedsOverlay.Draw();
		}
	}
	public static class NeedsOverlay
	{
		private sealed class Row
		{
			public readonly string Name;

			public readonly Func<Human, float> Read;

			public float Last = float.NaN;

			public float Drift;

			public float Hours;

			public float Rate
			{
				get
				{
					if (!(Hours > 0f))
					{
						return 0f;
					}
					return Drift / Hours;
				}
			}

			public Row(string name, Func<Human, float> read)
			{
				Name = name;
				Read = read;
			}
		}

		public static bool Visible;

		private const float SampleEvery = 1f;

		private const float Jump = 0.05f;

		private const float MaxStep = 0.1f;

		private const int KeepEvents = 4;

		private static readonly List<Row> Rows = new List<Row>
		{
			new Row("food", (Human h) => h.nourishment),
			new Row("water", (Human h) => h.hydration),
			new Row("energy", (Human h) => h.energy),
			new Row("alert", (Human h) => h.alertness),
			new Row("rested", (Human h) => h.wellRested),
			new Row("hygiene", (Human h) => h.hygiene),
			new Row("heat", (Human h) => h.heat),
			new Row("bladder", (Human h) => h.bladder),
			new Row("wet", (Human h) => h.wet),
			new Row("illness", (Human _) => Illness.Level),
			new Row("sick", (Human h) => h.sick),
			new Row("drunk", (Human h) => h.drunk),
			new Row("headache", (Human h) => h.headache),
			new Row("starch", (Human h) => h.starchAddiction),
			new Row("numb", (Human h) => h.numb),
			new Row("poisoned", (Human h) => h.poisoned),
			new Row("blinded", (Human h) => h.blinded),
			new Row("bleeding", (Human h) => h.bleeding),
			new Row("bruised", (Human h) => h.bruised),
			new Row("black eye", (Human h) => h.blackEye),
			new Row("broken leg", (Human h) => h.brokenLeg),
			new Row("health", (Human h) => ((Actor)h).currentHealth)
		};

		private static float _nextSample;

		private static float _lastGameTime = float.NaN;

		private static string _text = "";

		private static readonly List<string> Events = new List<string>();

		private static GUIStyle? _style;

		public static void Tick()
		{
			if (!Visible || Time.unscaledTime < _nextSample)
			{
				return;
			}
			_nextSample = Time.unscaledTime + 1f;
			Player instance = Player.Instance;
			Human val = ((instance != null) ? ((Il2CppObjectBase)instance).TryCast<Human>() : null);
			SessionData instance2 = SessionData.Instance;
			if ((Object)(object)val == (Object)null || (Object)(object)instance2 == (Object)null)
			{
				_text = "no player";
				return;
			}
			float gameTime = instance2.gameTime;
			float num = (float.IsNaN(_lastGameTime) ? 0f : (gameTime - _lastGameTime));
			_lastGameTime = gameTime;
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(19, 2, stringBuilder2);
			handler.AppendLiteral("<b>me</b>   game ");
			handler.AppendFormatted(gameTime, "F2");
			handler.AppendLiteral(" h");
			handler.AppendFormatted((num <= 0f) ? "  (paused)" : "");
			stringBuilder3.AppendLine(ref handler);
			stringBuilder.AppendLine("               now     /h");
			foreach (Row row in Rows)
			{
				float num2 = row.Read(val);
				if (num > 0f && num < 0.1f && !float.IsNaN(row.Last))
				{
					float num3 = num2 - row.Last;
					if (Mathf.Abs(num3) > 0.05f)
					{
						Events.Add($"{gameTime:F2}h {row.Name} {num3:+0.00;-0.00} -> {num2:F2}");
						if (Events.Count > 4)
						{
							Events.RemoveAt(0);
						}
					}
					else
					{
						row.Drift += num3;
						row.Hours += num;
					}
				}
				row.Last = num2;
				string value = ((Mathf.Abs(row.Rate) < 0.0005f) ? "" : row.Rate.ToString("+0.000;-0.000"));
				string text = $"{row.Name,-11}{num2,7:F3}  {value,7}";
				stringBuilder.AppendLine((num2 != 0f && IsEventful(row.Name)) ? ("<color=#ffcc66>" + text + "</color>") : text);
			}
			if (Events.Count > 0)
			{
				stringBuilder.AppendLine();
				foreach (string @event in Events)
				{
					stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder4 = stringBuilder2;
					handler = new StringBuilder.AppendInterpolatedStringHandler(23, 1, stringBuilder2);
					handler.AppendLiteral("<color=#aaaaaa>");
					handler.AppendFormatted(@event);
					handler.AppendLiteral("</color>");
					stringBuilder4.AppendLine(ref handler);
				}
			}
			_text = stringBuilder.ToString();
		}

		private static bool IsEventful(string name)
		{
			switch (name)
			{
			case "blinded":
			case "illness":
			case "bruised":
			case "numb":
			case "sick":
			case "bleeding":
			case "headache":
			case "poisoned":
			case "wet":
			case "drunk":
			case "starch":
			case "black eye":
			case "broken leg":
				return true;
			default:
				return false;
			}
		}

		public static void Draw()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_0021: 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_0035: Expected O, but got Unknown
			if (!Visible)
			{
				return;
			}
			if (_style == null)
			{
				_style = new GUIStyle(GUI.skin.label)
				{
					fontSize = 14,
					richText = true
				};
				try
				{
					_style.font = Font.CreateDynamicFontFromOSFont(Il2CppStringArray.op_Implicit(new string[4] { "Consolas", "DejaVu Sans Mono", "Liberation Mono", "Courier New" }), 14);
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] overlay: no monospace font (");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
					}
					log.LogWarning(val);
				}
			}
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor((float)Screen.width - 280f - 10f, 10f, 280f, 500f);
			GUI.Box(val2, "");
			GUI.Label(new Rect(((Rect)(ref val2)).x + 8f, ((Rect)(ref val2)).y + 6f, 264f, 488f), _text, _style);
		}

		public static void Toggle()
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			Visible = !Visible;
			_nextSample = 0f;
			_lastGameTime = float.NaN;
			Events.Clear();
			foreach (Row row in Rows)
			{
				row.Last = float.NaN;
				row.Drift = 0f;
				row.Hours = 0f;
			}
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(13, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] overlay ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Visible ? "on" : "off");
			}
			log.LogInfo(val);
		}
	}
	public static class Remedies
	{
		private sealed record Remedy(string Preset, float Hours, float Energy, params string[] Relieves);

		[HarmonyPatch(typeof(FirstPersonItemController), "SetConsuming")]
		public static class StartedConsuming
		{
			[HarmonyPrefix]
			public static void Prefix(FirstPersonItemController __instance, out bool __state)
			{
				__state = __instance.isConsuming;
			}

			[HarmonyPostfix]
			public static void Postfix(FirstPersonItemController __instance, bool __state)
			{
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Expected O, but got Unknown
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Expected O, but got Unknown
				if (__state || !__instance.isConsuming)
				{
					return;
				}
				bool flag = default(bool);
				try
				{
					BioScreenController instance = BioScreenController.Instance;
					object obj;
					if (instance == null)
					{
						obj = null;
					}
					else
					{
						InventorySlot selectedSlot = instance.selectedSlot;
						obj = ((selectedSlot != null) ? selectedSlot.GetInteractable() : null);
					}
					object obj2;
					if (obj == null)
					{
						obj2 = null;
					}
					else
					{
						InteractablePreset preset = ((Interactable)obj).preset;
						obj2 = ((preset != null) ? ((SoCustomComparison)preset).presetName : null);
					}
					string text = (string)obj2;
					if (Plugin.Cfg.DebugLogging.Value)
					{
						ManualLogSource log = Plugin.Log;
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(15, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] consuming ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text ?? "(unknown)");
						}
						log.LogInfo(val);
					}
					if (text != null)
					{
						Took(text);
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log2 = Plugin.Log;
					BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(35, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[me] could not tell what you took: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
					}
					log2.LogError(val2);
				}
			}
		}

		private static readonly Remedy[] All = new Remedy[3]
		{
			new Remedy("Painkillers", 4f, 0f, "Headache"),
			new Remedy("CoughMedicine", 6f, -0.3f, "Fever", "StuffyNose"),
			new Remedy("HeatPack", 2f, 0f, "Chills")
		};

		private const float ToleranceWindow = 24f;

		private const float TolerancePerDose = 0.67f;

		private const float MinEffect = 0.25f;

		private static Dictionary<string, float> _until = new Dictionary<string, float>();

		private static Dictionary<string, List<float>> _doses = new Dictionary<string, List<float>>();

		public static bool Relieved(string symptom)
		{
			SessionData instance = SessionData.Instance;
			if ((Object)(object)instance != (Object)null && _until.TryGetValue(symptom, out var value))
			{
				return instance.gameTime < value;
			}
			return false;
		}

		public static Dictionary<string, float> SaveRelief()
		{
			return new Dictionary<string, float>(_until);
		}

		public static Dictionary<string, List<float>> SaveDoses()
		{
			return _doses.ToDictionary<KeyValuePair<string, List<float>>, string, List<float>>((KeyValuePair<string, List<float>> p) => p.Key, (KeyValuePair<string, List<float>> p) => p.Value.ToList());
		}

		public static void Load(Dictionary<string, float>? relief, Dictionary<string, List<float>>? doses)
		{
			_until = relief ?? new Dictionary<string, float>();
			_doses = doses ?? new Dictionary<string, List<float>>();
		}

		private static void Took(string presetName)
		{
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			Remedy remedy = All.FirstOrDefault((Remedy r) => r.Preset == presetName);
			SessionData instance = SessionData.Instance;
			if (remedy == null || (Object)(object)instance == (Object)null)
			{
				return;
			}
			float now = instance.gameTime;
			if (!_doses.TryGetValue(presetName, out List<float> value))
			{
				value = (_doses[presetName] = new List<float>());
			}
			value.RemoveAll((float t) => t < now - 24f || t > now);
			int count = value.Count;
			value.Add(now);
			float num = remedy.Hours * Math.Max(0.25f, (float)Math.Pow(0.6700000166893005, count));
			float num2 = now + num;
			string[] relieves = remedy.Relieves;
			foreach (string key in relieves)
			{
				_until[key] = num2;
			}
			if (remedy.Energy != 0f)
			{
				Player instance2 = Player.Instance;
				if (instance2 != null)
				{
					((Human)instance2).AddEnergy(remedy.Energy);
				}
			}
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(49, 6, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] took ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(presetName);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (dose ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(count + 1);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" in ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(24f, "0");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("h): ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(", ", remedy.Relieves));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" relieved for ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num, "F1");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("h, until ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num2, "F2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("h");
			}
			log.LogInfo(val);
		}
	}
	public static class SelfProbe
	{
		[HarmonyPatch(typeof(Player), "AddNourishment")]
		public static class Food
		{
			[HarmonyPostfix]
			public static void Postfix(Player __instance, float addVal)
			{
				Note("food", addVal, ((Human)__instance).nourishment);
			}
		}

		[HarmonyPatch(typeof(Player), "AddHydration")]
		public static class Water
		{
			[HarmonyPostfix]
			public static void Postfix(Player __instance, float addVal)
			{
				Note("water", addVal, ((Human)__instance).hydration);
			}
		}

		[HarmonyPatch(typeof(Player), "AddEnergy")]
		public static class Rest
		{
			[HarmonyPostfix]
			public static void Postfix(Player __instance, float addVal)
			{
				Note("energy", addVal, ((Human)__instance).energy);
			}
		}

		[HarmonyPatch(typeof(Player), "AddAlertness")]
		public static class Alert
		{
			[HarmonyPostfix]
			public static void Postfix(Player __instance, float addVal)
			{
				Note("alertness", addVal, ((Human)__instance).alertness);
			}
		}

		[HarmonyPatch(typeof(Player), "AddHygiene")]
		public static class Clean
		{
			[HarmonyPostfix]
			public static void Postfix(Player __instance, float addVal)
			{
				Note("hygiene", addVal, ((Human)__instance).hygiene);
			}
		}

		[HarmonyPatch(typeof(Player), "AddHeat")]
		public static class Warmth
		{
			[HarmonyPostfix]
			public static void Postfix(Player __instance, float addVal)
			{
				Note("heat", addVal, ((Human)__instance).heat);
			}
		}

		[HarmonyPatch(typeof(Player), "AddSick")]
		public static class Illness
		{
			[HarmonyPostfix]
			public static void Postfix(Player __instance, float addVal)
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Expected O, but got Unknown
				if (addVal != 0f && Plugin.Cfg.DebugLogging.Value)
				{
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(14, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] SICK ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(addVal, "+0.000;-0.000");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(((Human)__instance).sick, "F2");
					}
					log.LogInfo(val);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "AddWet")]
		public static class Rain
		{
			[HarmonyPostfix]
			public static void Postfix(Player __instance, float addVal)
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Expected O, but got Unknown
				if (addVal != 0f && Plugin.Cfg.DebugLogging.Value)
				{
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(13, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] WET ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(addVal, "+0.000;-0.000");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(((Human)__instance).wet, "F2");
					}
					log.LogInfo(val);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "AddHeadache")]
		public static class Ache
		{
			[HarmonyPostfix]
			public static void Postfix(Player __instance, float addVal)
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Expected O, but got Unknown
				if (addVal != 0f && Plugin.Cfg.DebugLogging.Value)
				{
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] HEADACHE ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(addVal, "+0.000;-0.000");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(((Human)__instance).headache, "F2");
					}
					log.LogInfo(val);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "AddDrunk")]
		public static class Booze
		{
			[HarmonyPostfix]
			public static void Postfix(Player __instance, float addVal)
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Expected O, but got Unknown
				if (addVal != 0f && Plugin.Cfg.DebugLogging.Value)
				{
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(15, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] DRUNK ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(addVal, "+0.000;-0.000");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(((Human)__instance).drunk, "F2");
					}
					log.LogInfo(val);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "AddStarchAddiction")]
		public static class Kola
		{
			[HarmonyPostfix]
			public static void Postfix(float addVal)
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Expected O, but got Unknown
				if (addVal != 0f && Plugin.Cfg.DebugLogging.Value)
				{
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(22, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] STARCH ADDICTION ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(addVal, "+0.000;-0.000");
					}
					log.LogInfo(val);
				}
			}
		}

		private const float Noticeable = 0.01f;

		private static void Note(string field, float delta, float now)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			if (Plugin.Cfg.DebugLogging.Value && !(Math.Abs(delta) < 0.01f))
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(10, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(field);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(delta, "+0.00;-0.00");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(now, "F2");
				}
				log.LogInfo(val);
			}
		}
	}
	public static class Shelf
	{
		private const float StrongDrink = 1f;

		private static bool _done;

		public static void Apply()
		{
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			if (_done)
			{
				return;
			}
			Toolbox instance = Toolbox.Instance;
			Dictionary<string, InteractablePreset> val = ((instance != null) ? instance.objectPresetDictionary : null);
			if (val == null || val.Count == 0)
			{
				return;
			}
			_done = true;
			if (!Plugin.Cfg.RealisticDrinks.Value)
			{
				Plugin.Log.LogInfo((object)"[me] shelf: vanilla drinks kept");
				return;
			}
			float value = Plugin.Cfg.StrongDrinkThirst.Value;
			float value2 = Plugin.Cfg.StrongDrinkTiring.Value;
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			Enumerator<string, InteractablePreset> enumerator = val.GetEnumerator();
			while (enumerator.MoveNext())
			{
				InteractablePreset value3 = enumerator.Current.Value;
				RetailItemPreset val2 = ((value3 != null) ? value3.retailItem : null);
				if (!((SoCustomComparison)(object)val2 == (SoCustomComparison)null))
				{
					if (val2.drunk >= 1f)
					{
						val2.hydration = 0f - value;
						val2.energy = 0f - value2;
						num++;
					}
					if (val2.drunk < 0f)
					{
						val2.drunk = 0f;
						num2++;
					}
					if (val2.numb < 0f && val2.hydration > 0f)
					{
						val2.numb = 0f;
						num3++;
					}
				}
			}
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(96, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[me] shelf: ");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" strong drinks now dehydrate, ");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num2);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" no longer sober you up, ");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num3);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" no longer cancel painkillers");
			}
			log.LogInfo(val3);
		}
	}
	public static class Starvation
	{
		private sealed class Need
		{
			public readonly string Name;

			public readonly string Title;

			public readonly string Description;

			public readonly string Source;

			public StatusPreset? Preset;

			public bool Active;

			public StatusCount? Count;

			public bool JustShown;

			public Need(string name, string title, string description, string source)
			{
				Name = name;
				Title = title;
				Description = description;
				Source = source;
			}
		}

		[HarmonyPatch(typeof(StatusController), "ForceStatusCheck", new Type[] { typeof(bool) })]
		public static class StatusCheck
		{
			[HarmonyPrefix]
			public static void Prefix(StatusController __instance)
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Expected O, but got Unknown
				try
				{
					Sync(__instance);
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] needs sync failed: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogError(val);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Trip")]
		public static class NoFatalTrip
		{
			[HarmonyPrefix]
			public static void Prefix(Player __instance, ref float damage)
			{
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Expected O, but got Unknown
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Expected O, but got Unknown
				if (!Starving.Active && !Parched.Active)
				{
					return;
				}
				float num = Mathf.Max(0f, ((Actor)__instance).currentHealth - Floor(__instance));
				bool flag = default(bool);
				if (damage > num)
				{
					ManualLogSource log = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(36, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] trip damage ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(damage, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (health floor)");
					}
					log.LogInfo(val);
					damage = num;
				}
				else
				{
					ManualLogSource log2 = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] tripped: damage ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(damage, "F2");
					}
					log2.LogInfo(val);
				}
			}
		}

		private const float ThirstyLevel = 0.2f;

		private static readonly Need Starving = new Need("Starving", "Starving", "You haven't eaten in far too long. Health recovery is inactive, you are unsteady on your feet and slowly losing health. Eat something.", "Hungry");

		private static readonly Need Parched = new Need("Parched", "Parched", "You are badly dehydrated. Health recovery is inactive, you are dizzy, unsteady on your feet and slowly losing health. Drink something.", "Thirsty");

		private static readonly Need[] All = new Need[2] { Starving, Parched };

		private static bool _created;

		private static float _damage;

		private static float _headache;

		public static bool IsStarving => Starving.Active;

		public static bool IsParched => Parched.Active;

		public static void Apply(Player player, float dt)
		{
			if (!_created)
			{
				_created = Create();
			}
			Game instance = Game.Instance;
			Settings cfg = Plugin.Cfg;
			bool active = cfg.Starving.Value && (Object)(object)instance != (Object)null && instance.hungerStatusEnabled && ((Human)player).nourishment <= cfg.StarvingBelow.Value;
			bool active2 = cfg.Parched.Value && (Object)(object)instance != (Object)null && instance.hydrationStatusEnabled && ((Human)player).hydration <= cfg.ParchedBelow.Value;
			if (Set(Starving, active, ((Human)player).nourishment) | Set(Parched, active2, ((Human)player).hydration))
			{
				StatusController instance2 = StatusController.Instance;
				if (instance2 != null)
				{
					instance2.ForceStatusCheck();
				}
			}
			if (!(dt <= 0f) && !((Actor)player).isDead && !player.playerKOInProgress)
			{
				Hurt(player, dt);
				ThirstHeadache(player, instance, dt);
			}
		}

		private static bool Set(Need n, bool active, float value)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			active &= (SoCustomComparison)(object)n.Preset != (SoCustomComparison)null;
			if (active == n.Active)
			{
				return false;
			}
			n.Active = active;
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(10, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(n.Name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(active ? "on" : "off");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" at ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(value, "F2");
			}
			log.LogInfo(val);
			return true;
		}

		private static void Hurt(Player player, float dt)
		{
			float num = (Starving.Active ? Plugin.Cfg.StarvingDamage.Value : 0f) + (Parched.Active ? Plugin.Cfg.ParchedDamage.Value : 0f);
			if (num <= 0f)
			{
				_damage = 0f;
				return;
			}
			_damage += num * ((Actor)player).maximumHealth * dt;
			if (!(_damage < 0.01f))
			{
				float num2 = ((Actor)player).currentHealth - Floor(player);
				float num3 = Mathf.Min(_damage, num2);
				_damage = 0f;
				if (num3 > 0f)
				{
					((Actor)player).AddHealth(0f - num3, false, false);
				}
			}
		}

		private static float Floor(Player player)
		{
			return Mathf.Clamp01(Plugin.Cfg.HealthFloor.Value) * ((Actor)player).maximumHealth;
		}

		private static void ThirstHeadache(Player player, Game? game, float dt)
		{
			float value = Plugin.Cfg.ThirstHeadachePerHour.Value;
			if (value <= 0f || (Object)(object)game == (Object)null || !game.hydrationStatusEnabled || ((Human)player).hydration > 0.2f || Remedies.Relieved("Headache"))
			{
				_headache = 0f;
				return;
			}
			_headache += value * dt;
			if (!(_headache < 0.02f))
			{
				((Human)player).AddHeadache(_headache);
				_headache = 0f;
			}
		}

		private static bool Create()
		{
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			Toolbox instance = Toolbox.Instance;
			List<StatusPreset> val = ((instance != null) ? instance.allStatuses : null);
			if (val == null)
			{
				return false;
			}
			Need[] all = All;
			bool flag = default(bool);
			foreach (Need need in all)
			{
				StatusPreset val2 = null;
				Enumerator<StatusPreset> enumerator = val.GetEnumerator();
				while (enumerator.MoveNext())
				{
					StatusPreset current = enumerator.Current;
					if ((SoCustomComparison)(object)current != (SoCustomComparison)null && ((Object)current).name == need.Source)
					{
						val2 = current;
					}
				}
				if ((SoCustomComparison)(object)val2 == (SoCustomComparison)null)
				{
					ManualLogSource log = Plugin.Log;
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(29, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[me] no '");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(need.Source);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' status to base ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(need.Name);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" on");
					}
					log.LogWarning(val3);
				}
				else
				{
					StatusPreset val4 = Object.Instantiate<StatusPreset>(val2);
					((Object)val4).name = need.Name;
					((SoCustomComparison)val4).presetName = need.Name;
					((Object)val4).hideFlags = (HideFlags)32;
					ClearEffects(val4);
					val4.stopsRecovery = true;
					val4.tripChanceDrunk = Mathf.Max(0f, Plugin.Cfg.StumbleChance.Value);
					StatusIcons.Apply(val4, need.Name, val2);
					need.Preset = val4;
					string text = need.Name.ToLowerInvariant();
					Lib.DdsStrings.AddOrUpdate("ui.states", text, need.Title);
					Lib.DdsStrings.AddOrUpdate("ui.states", text + "_description", need.Description);
				}
			}
			if (Plugin.Cfg.ThirstHeadachePerHour.Value > 0f)
			{
				AppendHint("thirsty_description", "Going thirsty for long gives you a headache.");
			}
			ManualLogSource log2 = Plugin.Log;
			BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[me] needs ready: ");
				((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(string.Join(", ", from n in All
					where (SoCustomComparison)(object)n.Preset != (SoCustomComparison)null
					select n.Name));
			}
			log2.LogInfo(val5);
			return true;
		}

		private static void AppendHint(string key, string hint)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			try
			{
				string text = Lib.DdsStrings.Get("ui.states", key) ?? "";
				if (!text.Contains(hint))
				{
					Lib.DdsStrings.AddOrUpdate("ui.states", key, text.TrimEnd() + " " + hint);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(24, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] could not extend ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(key);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}

		private static void ClearEffects(StatusPreset p)
		{
			bool flag = (p.stopsJump = false);
			bool stopsRecovery = (p.stopsSprint = flag);
			p.stopsRecovery = stopsRecovery;
			float num = (p.movementSpeedPlusMP = 0f);
			float recoveryRatePlusMP = (p.maxHealthPlusMP = num);
			p.recoveryRatePlusMP = recoveryRatePlusMP;
			num = (p.damageOutgoingPlusMP = 0f);
			recoveryRatePlusMP = (p.damageIncomingPlusMP = num);
			p.temperatureGainPlusMP = recoveryRatePlusMP;
			float num6 = (p.affectHeadBob = 0f);
			num = (p.tripChanceDrunk = num6);
			recoveryRatePlusMP = (p.tripChanceWet = num);
			p.drunkControls = recoveryRatePlusMP;
			num6 = (p.drunkLensDistort = 0f);
			num = (p.headacheVision = num6);
			recoveryRatePlusMP = (p.shiverVision = num);
			p.drunkVision = recoveryRatePlusMP;
			num = (p.chromaticAbberationAmount = 0f);
			recoveryRatePlusMP = (p.motionBlurPlusMP = num);
			p.bloomIntensityPlusMP = recoveryRatePlusMP;
			recoveryRatePlusMP = (p.expsosure = 0f);
			p.vignetteAmount = recoveryRatePlusMP;
			p.useChannelMixer = false;
		}

		private static void Sync(StatusController controller)
		{
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//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_00c1: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			HashSet<StatusPreset> activeStatuses = controller.activeStatuses;
			if (activeStatuses == null)
			{
				return;
			}
			Need[] all = All;
			bool flag2 = default(bool);
			foreach (Need need in all)
			{
				if ((SoCustomComparison)(object)need.Preset == (SoCustomComparison)null)
				{
					continue;
				}
				if (need.Count != null && !activeStatuses.Contains(need.Preset) && !need.JustShown)
				{
					need.Count = null;
				}
				need.JustShown = false;
				bool flag = need.Count != null;
				if (need.Active == flag)
				{
					continue;
				}
				if (need.Active)
				{
					ManualLogSource log = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(13, 1, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] showing ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(need.Name);
					}
					log.LogInfo(val);
					StatusInstance val2 = new StatusInstance
					{
						preset = need.Preset
					};
					need.Count = new StatusCount(val2)
					{
						amount = 1f
					};
					need.JustShown = true;
				}
				else
				{
					ManualLogSource log2 = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(12, 1, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] hiding ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(need.Name);
					}
					log2.LogInfo(val);
					need.Count.Remove();
					activeStatuses.Remove(need.Preset);
					need.Count = null;
				}
			}
		}
	}
	public static class StatusIcons
	{
		public static void Apply(StatusPreset preset, string name, StatusPreset source)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			try
			{
				Sprite val = Load(name, source.icon);
				if (!((Object)(object)val == (Object)null))
				{
					preset.icon = val;
					if ((Object)(object)source.alternateIcon != (Object)null)
					{
						preset.alternateIcon = val;
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(31, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[me] no icon for ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(name);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", keeping ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)source).name);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'s: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val2);
			}
		}

		private static Sprite? Load(string name, Sprite? like)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			using Stream stream = typeof(StatusIcons).Assembly.GetManifestResourceStream("CreatureDiscomforts.assets.status." + name + ".png");
			if (stream == null)
			{
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(memoryStream.ToArray())))
			{
				return null;
			}
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Object)val).hideFlags = (HideFlags)32;
			float num = (((Object)(object)like != (Object)null) ? like.pixelsPerUnit : 100f);
			Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), num);
			((Object)obj).name = name;
			((Object)obj).hideFlags = (HideFlags)32;
			return obj;
		}
	}
	public static class Stomach
	{
		[HarmonyPatch(typeof(Player), "AddDrunk")]
		public static class Overdrink
		{
			[HarmonyPrefix]
			public static void Prefix(Player __instance, float addVal)
			{
				if (addVal <= 0f)
				{
					return;
				}
				float value = Plugin.Cfg.OverdrinkNausea.Value;
				if (!(value <= 0f))
				{
					float num = ((Human)__instance).drunk + addVal - 1f;
					if (num > 0f)
					{
						((Human)__instance).AddSick(value * Mathf.Min(num, addVal));
					}
				}
			}
		}

		[HarmonyPatch(typeof(Player), "AddSick")]
		public static class VomitProgress
		{
			[HarmonyPostfix]
			public static void Postfix(Player __instance, float addVal)
			{
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Expected O, but got Unknown
				if (addVal >= 0f)
				{
					return;
				}
				InteractionController instance = InteractionController.Instance;
				if ((Object)(object)instance == (Object)null || instance.interactionActionName != "Vomiting")
				{
					return;
				}
				if (!_reportedVomit)
				{
					_reportedVomit = true;
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(51, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] throwing up: sobers ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(Plugin.Cfg.VomitSobers.Value);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("tires ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(Plugin.Cfg.VomitTiring.Value);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" per full throw-up");
					}
					log.LogInfo(val);
				}
				Aftermath(__instance, 0f - addVal);
			}
		}

		private const string Vomiting = "Vomiting";

		private const float MaxStep = 1f;

		private static float _lastGameTime = float.NaN;

		private static SpatterPatternPreset? _vomit;

		private static readonly Color Bile = new Color(0.62f, 0.55f, 0.22f, 1f);

		private static readonly string[] ColorProps = new string[4] { "_BaseColor", "_Color", "_TintColor", "_MainColor" };

		private const float DrunkCap = 1f;

		private static bool _reportedVomit;

		public static void Tick()
		{
			SessionData instance = SessionData.Instance;
			Player instance2 = Player.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null)
			{
				_lastGameTime = float.NaN;
				return;
			}
			float gameTime = instance.gameTime;
			float num = (float.IsNaN(_lastGameTime) ? 0f : (gameTime - _lastGameTime));
			_lastGameTime = gameTime;
			if (!(num <= 0f) && !(num > 1f))
			{
				float value = Plugin.Cfg.NauseaFromDrunk.Value;
				if (value > 0f && value < 1f && ((Human)instance2).drunk > value)
				{
					float num2 = Mathf.Clamp01((((Human)instance2).drunk - value) / (1f - value));
					((Human)instance2).AddSick(Plugin.Cfg.DrunkNauseaPerHour.Value * num2 * num);
				}
				MaybeRetch(instance2, num);
			}
		}

		private static void MaybeRetch(Player player, float dt)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Invalid comparison between Unknown and I4
			float value = Plugin.Cfg.RetchAbove.Value;
			float value2 = Plugin.Cfg.RetchPerHour.Value;
			if (value2 <= 0f || value >= 1f || ((Human)player).sick <= value)
			{
				return;
			}
			InteractionController instance = InteractionController.Instance;
			if ((Object)(object)instance == (Object)null || instance.activeInteractionAction)
			{
				return;
			}
			Interactable lockedInInteraction = instance.lockedInInteraction;
			InteractablePreset val = ((lockedInInteraction != null) ? lockedInInteraction.preset : null);
			if (!((SoCustomComparison)(object)val != (SoCustomComparison)null) || (int)val.specialCaseFlag != 1)
			{
				float num = Mathf.Clamp01((((Human)player).sick - value) / (1f - value));
				float num2 = 1f - Mathf.Exp((0f - value2) * num * dt);
				if (!(Random.value >= num2))
				{
					Retch(player);
				}
			}
		}

		private static void Retch(Player player)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Expected O, but got Unknown
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_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_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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(44, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] retching where you stand: sick ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(((Human)player).sick, "F2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", drunk ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(((Human)player).drunk, "F2");
			}
			log.LogInfo(val);
			((Human)player).AddSick(-1f);
			((Human)player).AddHygiene(-0.5f);
			Aftermath(player, 1f);
			try
			{
				SpatterPatternPreset val2 = VomitSpatter();
				Camera main = Camera.main;
				Transform val3 = ((main != null) ? ((Component)main).transform : null);
				if ((SoCustomComparison)(object)val2 != (SoCustomComparison)null && (Object)(object)val3 != (Object)null)
				{
					Vector3 position = val3.position;
					Vector3 val4 = Vector3.ProjectOnPlane(val3.forward, Vector3.up);
					Vector3 normalized = ((Vector3)(ref val4)).normalized;
					SpatterSimulation val5 = new SpatterSimulation(position, position + normalized * 0.6f + Vector3.down * 1.6f, val2, (EraseMode)4, 1f, true);
					if (!val5.isExecuted)
					{
						val5.Execute();
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val6 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("[me] no vomit on the floor: ");
					((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(ex.Message);
				}
				log2.LogWarning(val6);
			}
			try
			{
				Lib.GameMessage.Broadcast("You throw up.", (GameMessageType)0, (Icon)37, (Color?)null, 0f);
			}
			catch (Exception ex2)
			{
				ManualLogSource log3 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val6 = new BepInExWarningLogInterpolatedStringHandler(42, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("[me] could not show the retching message: ");
					((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(ex2.Message);
				}
				log3.LogWarning(val6);
			}
		}

		private static SpatterPatternPreset? VomitSpatter()
		{
			if ((SoCustomComparison)(object)_vomit != (SoCustomComparison)null)
			{
				return _vomit;
			}
			CitizenControls instance = CitizenControls.Instance;
			SpatterPatternPreset val = ((instance != null) ? instance.vomitSpatter : null);
			if ((SoCustomComparison)(object)val == (SoCustomComparison)null)
			{
				return null;
			}
			SpatterPatternPreset obj = Object.Instantiate<SpatterPatternPreset>(val);
			obj.heavyMaterial = Tint(val.heavyMaterial);
			obj.mediumMaterial = Tint(val.mediumMaterial);
			obj.lightMaterial = Tint(val.lightMaterial);
			_vomit = obj;
			return obj;
		}

		private static Material? Tint(Material? vanilla)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			//IL_0034: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)vanilla == (Object)null)
			{
				return null;
			}
			Material val = new Material(vanilla);
			string text = "none";
			string[] colorProps = ColorProps;
			foreach (string text2 in colorProps)
			{
				if (val.HasProperty(text2))
				{
					Color color = val.GetColor(text2);
					val.SetColor(text2, new Color(Bile.r, Bile.g, Bile.b, color.a));
					text = $"{text2} was {color}";
				}
			}
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(25, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[me] vomit material ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)vanilla).name);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (");
				Shader shader = vanilla.shader;
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>((shader != null) ? ((Object)shader).name : null);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("): ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text);
			}
			log.LogInfo(val2);
			return val;
		}

		private static void Aftermath(Player player, float part)
		{
			float value = Plugin.Cfg.VomitSobers.Value;
			float value2 = Plugin.Cfg.VomitTiring.Value;
			if (value > 0f && ((Human)player).drunk > 0f)
			{
				((Human)player).AddDrunk((0f - value) * part);
			}
			if (value2 > 0f)
			{
				((Human)player).AddEnergy((0f - value2) * part);
			}
		}
	}
	public static class Symptoms
	{
		private sealed class Symptom
		{
			public readonly string Name;

			public readonly string Title;

			public readonly string Description;

			public readonly string Source;

			public readonly float Threshold;

			public readonly float ExtraThirst;

			public readonly float ExtraTiredness;

			public float HygienePerHour;

			public float HeadachePerHour;