Decompiled source of Flatline IL2CPP v1.0.2

Mods/Flatline-IL2Cpp.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using Flatline;
using HarmonyLib;
using Il2CppFishNet;
using Il2CppFishNet.Managing;
using Il2CppFishNet.Managing.Object;
using Il2CppFishNet.Object;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.Audio;
using Il2CppScheduleOne.AvatarFramework;
using Il2CppScheduleOne.Building.Doors;
using Il2CppScheduleOne.Combat;
using Il2CppScheduleOne.Core.Audio;
using Il2CppScheduleOne.Core.Items.Framework;
using Il2CppScheduleOne.Core.Weather;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Dialogue;
using Il2CppScheduleOne.Doors;
using Il2CppScheduleOne.EntityFramework;
using Il2CppScheduleOne.Equipping;
using Il2CppScheduleOne.FX;
using Il2CppScheduleOne.GameTime;
using Il2CppScheduleOne.Interaction;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Map;
using Il2CppScheduleOne.Money;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.NPCs.CharacterClasses;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.PlayerScripts.Health;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Property;
using Il2CppScheduleOne.Temperature;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.MainMenu;
using Il2CppScheduleOne.UI.Phone;
using Il2CppScheduleOne.UI.Phone.Messages;
using Il2CppScheduleOne.VoiceOver;
using Il2CppScheduleOne.Weather;
using Il2CppSystem;
using Il2CppSystem.Collections;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Support;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(global::Flatline.Flatline), "Flatline", "1.0.2", "XOWithSauce", "https://github.com/XOWithSauce/schedule-flatline")]
[assembly: MelonColor]
[assembly: MelonOptionalDependencies(new string[] { "FishNet.Runtime", "Il2Cpp" })]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)]
[assembly: VerifyLoaderVersion("0.7.2", true)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("XOWithSauce")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright XOWithSauce 2026 Source MIT")]
[assembly: AssemblyDescription("Schedule I Flatline Mod")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("Flatline")]
[assembly: AssemblyTitle("Flatline-IL2Cpp")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/XOWithSauce/schedule-flatline")]
[assembly: NeutralResourcesLanguage("en-US")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Flatline
{
	public static class BedRotSimulator
	{
		public static bool isBedrotting = false;

		public static bool isInitialized = false;

		public static bool isEvaluatingBedState = false;

		public static readonly float energyRegenPerMinute = FlatlinePlayer.DefaultEnergyConsumption + 0.003f;

		public static readonly float healthRegenPerMinuteTarget = FlatlinePlayer.DefaultHealthRegeneration * 5f;

		public static readonly float healthRegenT = FlatlinePlayer.SystematicHomeostasisSpeed * 10f;

		public static IEnumerator InitBedRotModule()
		{
			yield return (object)new WaitUntil(Func<bool>.op_Implicit((Func<bool>)(() => NetworkManager._instances != null && NetworkManager._instances.Count > 0)));
			NetworkManager instance = NetworkManager._instances[0];
			yield return (object)new WaitUntil(Func<bool>.op_Implicit((Func<bool>)(() => instance.Initialized)));
			PrepareBedRotInteractable();
			DebugModule.Log("Bed prefab changed succesfully", "InitBedRotModule");
			isInitialized = true;
		}

		public static void ResetBedRotModule()
		{
			isBedrotting = false;
			isEvaluatingBedState = false;
		}

		public static void PrepareBedRotInteractable()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			PrefabObjects spawnablePrefabs = Object.FindObjectOfType<NetworkManager>(true).SpawnablePrefabs;
			for (int i = 0; i < spawnablePrefabs.GetObjectCount(); i++)
			{
				NetworkObject val = spawnablePrefabs.GetObject(true, i);
				if (((val != null) ? ((Object)((Component)val).gameObject).name : null).Contains("SingleBed"))
				{
					((Component)val).GetComponent<Bed>();
					GameObject val2 = new GameObject("BedRotIntObj");
					val2.transform.parent = ((Component)val).transform;
					((Object)val2.gameObject).name = "BedRotIntObj";
					val2.transform.position = new Vector3(0f, 0.264f, 0.8f);
					BoxCollider val3 = val2.AddComponent<BoxCollider>();
					((Collider)val3).isTrigger = true;
					InteractableObject val4 = val2.AddComponent<InteractableObject>();
					val4.message = "Rot in the bed";
					val4.SetInteractableState((EInteractableState)0);
					val2.SetActive(true);
					((Collider)val3).enabled = true;
					((Behaviour)val4).enabled = true;
				}
			}
		}

		public static void BedRotInteracted(InteractableObject intObj, Bed bed)
		{
			if (!isBedrotting)
			{
				isBedrotting = true;
				Flatline.coros.Add(MelonCoroutines.Start(BedRotSimulatorRunner(intObj, bed)));
			}
		}

		public static void BedRotInteractableHovered(InteractableObject intObj, Bed bed)
		{
			if (!isEvaluatingBedState)
			{
				isEvaluatingBedState = true;
				Flatline.coros.Add(MelonCoroutines.Start(EvaluateBedState(intObj, bed)));
			}
		}

		public static IEnumerator EvaluateBedState(InteractableObject intObj, Bed bed)
		{
			if (Player.Local.IsSkating)
			{
				intObj.SetInteractableState((EInteractableState)1);
				intObj.message = "Can't bedrot while skateboarding";
			}
			else if ((Object)(object)bed.AssignedEmployee != (Object)null)
			{
				intObj.SetInteractableState((EInteractableState)1);
				intObj.message = "Can't bedrot in an employee's bed";
			}
			else if (NetworkSingleton<TimeManager>.Instance.IsCurrentTimeWithinRange(359, 700))
			{
				intObj.SetInteractableState((EInteractableState)1);
				intObj.message = "Can't bedrot at late night";
			}
			else
			{
				intObj.SetInteractableState((EInteractableState)0);
				intObj.message = "Rot in the bed";
			}
			yield return Flatline.Wait1;
			if (Flatline.registered)
			{
				isEvaluatingBedState = false;
			}
		}

		public static IEnumerator BedRotSimulatorRunner(InteractableObject intObj, Bed bed)
		{
			((Behaviour)intObj).enabled = false;
			((Behaviour)bed.intObj).enabled = false;
			PlayerSingleton<PlayerCamera>.Instance.SetCanLook(false);
			PlayerSingleton<PlayerMovement>.Instance.CanMove = false;
			((Behaviour)PlayerSingleton<PlayerMovement>.Instance).enabled = false;
			((Collider)Player.Local.CapCol).enabled = false;
			Transform playerTrRoot = ((Component)Player.Local).transform.root;
			playerTrRoot.parent = ((Component)bed).transform;
			Vector3 originalStandPoint = playerTrRoot.localPosition;
			Quaternion originalRotation = playerTrRoot.localRotation;
			Vector3 targetLocalPosition = new Vector3(0.009f, 0.24f, 0.012f);
			Quaternion targetRotation = Quaternion.Euler(270f, 0f, 0f);
			float animationDuration = 3f;
			float elapsed = 0f;
			while (elapsed < animationDuration && Flatline.registered)
			{
				float num = elapsed / animationDuration;
				playerTrRoot.localPosition = Vector3.Lerp(originalStandPoint, targetLocalPosition, num);
				playerTrRoot.localRotation = Quaternion.Slerp(originalRotation, targetRotation, num);
				elapsed += Time.deltaTime;
				yield return null;
			}
			playerTrRoot.localPosition = targetLocalPosition;
			playerTrRoot.localRotation = targetRotation;
			PlayerSingleton<PlayerCamera>.Instance.SetCanLook(true);
			float maxY = 20f;
			while (Flatline.registered)
			{
				yield return Flatline.WaitFrame;
				if (Quaternion.Angle(playerTrRoot.localRotation, targetRotation) > maxY)
				{
					playerTrRoot.localRotation = Quaternion.Slerp(playerTrRoot.localRotation, targetRotation, 0.05f);
				}
				if ((!PlayerSingleton<Phone>.Instance.IsOpen && (Input.GetKey((KeyCode)32) || Input.GetKey((KeyCode)119) || Input.GetKey((KeyCode)97) || Input.GetKey((KeyCode)115) || Input.GetKey((KeyCode)100))) || FlatlinePlayer.isPassedOut || FlatlinePlayer.isQueuedForDeath)
				{
					break;
				}
			}
			PlayerSingleton<PlayerCamera>.Instance.SetCanLook(false);
			elapsed = 0f;
			Quaternion currentRotation = playerTrRoot.localRotation;
			while (elapsed < animationDuration && Flatline.registered)
			{
				float num2 = elapsed / animationDuration;
				playerTrRoot.localPosition = Vector3.Lerp(targetLocalPosition, originalStandPoint, num2);
				playerTrRoot.localRotation = Quaternion.Slerp(currentRotation, originalRotation, num2);
				elapsed += Time.deltaTime;
				yield return null;
			}
			playerTrRoot.localPosition = originalStandPoint;
			playerTrRoot.localRotation = originalRotation;
			playerTrRoot.parent = null;
			((Collider)Player.Local.CapCol).enabled = true;
			PlayerSingleton<PlayerCamera>.Instance.SetCanLook(true);
			((Behaviour)PlayerSingleton<PlayerMovement>.Instance).enabled = true;
			PlayerSingleton<PlayerMovement>.Instance.CanMove = true;
			((Behaviour)intObj).enabled = true;
			((Behaviour)bed.intObj).enabled = true;
			isBedrotting = false;
			AfterBedrotEnd();
		}

		public static void MinPassBedrotting()
		{
			if (!Flatline.registered || Flatline.isSaving || !isBedrotting || FlatlinePlayer.isQueuedForDeath || Flatline.haltExecution)
			{
				return;
			}
			if (Flatline.loadedPlayerData.State.Energy < 1f)
			{
				FlatlinePlayer.SetEnergy(Mathf.Clamp01(Flatline.loadedPlayerData.State.Energy + energyRegenPerMinute));
			}
			if (Flatline.loadedPlayerData.State.healthData.CurrentHP < Flatline.loadedPlayerData.State.healthData.MaxHP)
			{
				if (FlatlinePlayer.HealthRegenPerMinute < healthRegenPerMinuteTarget)
				{
					FlatlinePlayer.HealthRegenPerMinute = Mathf.Lerp(FlatlinePlayer.HealthRegenPerMinute, healthRegenPerMinuteTarget, healthRegenT);
				}
				if (Random.Range(0f, 1f) > 0.9f)
				{
					Player.Local.Health.CurrentHealth = Mathf.Clamp(Player.Local.Health.CurrentHealth + 1f, 0f, Flatline.loadedPlayerData.State.healthData.MaxHP);
					if (Flatline.loadedPlayerData.State.Energy < 1f)
					{
						Mathf.Clamp01(Flatline.loadedPlayerData.State.Energy + energyRegenPerMinute * 8f);
					}
				}
			}
			if (Flatline.loadedPlayerData.State.Hunger < 1f && Flatline.loadedPlayerData.State.Hunger > 0.1f && FlatlinePlayer.FoodConsumptionPerMinute > FlatlinePlayer.DefaultFoodConsumption / 2f)
			{
				FlatlinePlayer.FoodConsumptionPerMinute = Mathf.Lerp(FlatlinePlayer.FoodConsumptionPerMinute, FlatlinePlayer.DefaultFoodConsumption / 2f, FlatlinePlayer.SystematicHomeostasisSpeed * 1.55f);
			}
			if (Flatline.loadedPlayerData.State.Thirst < 1f && Flatline.loadedPlayerData.State.Thirst > 0.1f && FlatlinePlayer.ThirstConsumptionPerMinute > FlatlinePlayer.DefaultThirstConsumption / 2f)
			{
				FlatlinePlayer.ThirstConsumptionPerMinute = Mathf.Lerp(FlatlinePlayer.ThirstConsumptionPerMinute, FlatlinePlayer.DefaultThirstConsumption / 2f, FlatlinePlayer.SystematicHomeostasisSpeed * 1.55f);
			}
		}

		public static void AfterBedrotEnd()
		{
			if (FlatlinePlayer.HealthRegenPerMinute > FlatlinePlayer.DefaultHealthRegeneration)
			{
				FlatlinePlayer.HealthRegenPerMinute = Mathf.Lerp(FlatlinePlayer.HealthRegenPerMinute, FlatlinePlayer.DefaultHealthRegeneration, 0.5f);
			}
			if (FlatlinePlayer.FoodConsumptionPerMinute < FlatlinePlayer.DefaultFoodConsumption)
			{
				FlatlinePlayer.FoodConsumptionPerMinute = Mathf.Lerp(FlatlinePlayer.FoodConsumptionPerMinute, FlatlinePlayer.DefaultFoodConsumption, 0.5f);
			}
			if (FlatlinePlayer.ThirstConsumptionPerMinute < FlatlinePlayer.DefaultThirstConsumption)
			{
				FlatlinePlayer.ThirstConsumptionPerMinute = Mathf.Lerp(FlatlinePlayer.ThirstConsumptionPerMinute, FlatlinePlayer.DefaultThirstConsumption, 0.5f);
			}
		}
	}
	[HarmonyPatch(typeof(Bed), "Awake")]
	public static class Bed_Awake_Patch
	{
		[HarmonyPrefix]
		public static bool Prefix(Bed __instance)
		{
			Transform val = ((Component)__instance).transform.Find("BedRotIntObj");
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			InteractableObject bedRotInt = ((Component)val).gameObject.GetComponent<InteractableObject>();
			bedRotInt.onInteractStart.AddListener(UnityAction.op_Implicit((Action)OnBedRotInteraction));
			bedRotInt.onHovered.AddListener(UnityAction.op_Implicit((Action)OnBedRotHovered));
			return true;
			void OnBedRotHovered()
			{
				if (Flatline.registered)
				{
					BedRotSimulator.BedRotInteractableHovered(bedRotInt, __instance);
				}
			}
			void OnBedRotInteraction()
			{
				if (Flatline.registered)
				{
					BedRotSimulator.BedRotInteracted(bedRotInt, __instance);
				}
			}
		}
	}
	public static class DepressionSimulator
	{
		public static GameObject disabledOverlay;

		public static void InitiateDepressionSimulatorModule()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_00c5: 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_00d5: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			disabledOverlay = new GameObject("DisableOverlay");
			disabledOverlay.transform.SetParent(((Component)PlayerSingleton<MessagesApp>.Instance).transform, false);
			RectTransform obj = disabledOverlay.AddComponent<RectTransform>();
			obj.sizeDelta = new Vector2(800f, 1200f);
			((Transform)obj).localScale = Vector3.one;
			((Transform)obj).localPosition = Vector3.zero;
			((Transform)obj).localRotation = Quaternion.identity;
			((Graphic)disabledOverlay.AddComponent<Image>()).color = new Color(0.1f, 0.1f, 0.1f, 0.93f);
			GameObject val = new GameObject("Text");
			val.transform.SetParent(disabledOverlay.transform);
			val.transform.localScale = Vector3.one;
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.identity;
			val.AddComponent<RectTransform>().sizeDelta = new Vector2(600f, 1200f);
			TextMeshProUGUI obj2 = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)obj2).text = "You are too depressed right now";
			((TMP_Text)obj2).alignment = (TextAlignmentOptions)514;
			((TMP_Text)obj2).fontSize = 52f;
			disabledOverlay.SetActive(false);
			DebugModule.Log("Initiated depression simulator", "InitiateDepressionSimulatorModule");
		}

		public static void ResetDepressionSimulatorModule()
		{
			disabledOverlay = null;
		}

		public static bool ShouldSkip()
		{
			if (Player.PlayerList.Count > 1 && !Player.Local.Health.IsAlive)
			{
				return true;
			}
			if (NetworkSingleton<TimeManager>.Instance.CurrentTime < 659 && NetworkSingleton<TimeManager>.Instance.CurrentTime > 400)
			{
				return true;
			}
			if (Flatline.isSaving)
			{
				return true;
			}
			if (Flatline.haltExecution)
			{
				return true;
			}
			return false;
		}

		public static IEnumerator DepressionBlandWorld(Depression depression)
		{
			while (true)
			{
				yield return Flatline.Wait10;
				if (!Flatline.registered || !depression.data.Active || (FlatlinePlayer.isQueuedForDeath && Flatline.currentConfig.PermanentDeath))
				{
					break;
				}
				if (ShouldSkip() || depression.isTemporaryCurePresent)
				{
					continue;
				}
				float num = Mathf.Lerp(0.95f, 0.75f, depression.data.Severity / 0.3f);
				if (Random.Range(0f, 1f) < num)
				{
					continue;
				}
				float duration = Mathf.Lerp(Depression.minBlandEffectDuration, Depression.maxBlandEffectDuration, depression.data.Severity / 0.3f);
				float current = 0f;
				Singleton<PostProcessingManager>.Instance.SaturationController.AddOverride(-56f, 25, "Depression");
				do
				{
					yield return Flatline.Wait1;
					if (!Flatline.registered)
					{
						yield break;
					}
					current += 1f;
				}
				while (!(current >= duration) && depression.data.Active && !depression.isTemporaryCurePresent);
				Singleton<PostProcessingManager>.Instance.SaturationController.RemoveOverride("Depression");
			}
		}

		public static IEnumerator DepressionMessagerDisabler(Depression depression)
		{
			while (true)
			{
				yield return Flatline.Wait10;
				if (!Flatline.registered || !depression.data.Active || (FlatlinePlayer.isQueuedForDeath && Flatline.currentConfig.PermanentDeath))
				{
					break;
				}
				if (ShouldSkip() || depression.isTemporaryCurePresent)
				{
					continue;
				}
				float num = Mathf.Lerp(0.95f, 0.75f, depression.data.Severity / 0.3f);
				if (Random.Range(0f, 1f) < num)
				{
					continue;
				}
				float duration = Mathf.Lerp(Depression.minDisablerEffectDuration, Depression.maxDisablerEffectDuration, depression.data.Severity / 0.3f);
				float current = 0f;
				disabledOverlay.SetActive(true);
				do
				{
					yield return Flatline.Wait1;
					if (!Flatline.registered)
					{
						yield break;
					}
					current += 1f;
				}
				while (!(current >= duration) && depression.data.Active && !depression.isTemporaryCurePresent);
				disabledOverlay.SetActive(false);
			}
		}

		public static IEnumerator DepressionDoorDisabler(Depression depression)
		{
			while (true)
			{
				yield return Flatline.Wait10;
				if (!Flatline.registered || !depression.data.Active || (FlatlinePlayer.isQueuedForDeath && Flatline.currentConfig.PermanentDeath))
				{
					break;
				}
				if (ShouldSkip() || (int)Player.Local.CrimeData.CurrentPursuitLevel != 0 || depression.isTemporaryCurePresent)
				{
					continue;
				}
				float num = Mathf.Clamp01(((float)depression.data.Progression / 5f + depression.data.Severity / 0.3f) / 2f);
				float num2 = Mathf.Lerp(0.95f, 0.75f, num);
				if (Random.Range(0f, 1f) < num2 || !((Object)(object)Player.Local.CurrentProperty != (Object)null) || !Player.Local.CurrentProperty.IsOwned)
				{
					continue;
				}
				if (PropertyTemperatureController.propertyDoors.TryGetValue(Player.Local.CurrentProperty.propertyCode, out var doors))
				{
					PropertyDoorController[] array = doors;
					foreach (PropertyDoorController val in array)
					{
						if (!((DoorController)val).IsOpen)
						{
							((DoorController)val).PlayerAccess = (EDoorAccess)1;
							((DoorController)val).noAccessErrorMessage = "You are too depressed right now";
						}
					}
					float duration = Mathf.Lerp(Depression.minDisablerEffectDuration, Depression.maxDisablerEffectDuration, num);
					float current = 0f;
					do
					{
						yield return Flatline.Wait1;
						if (!Flatline.registered)
						{
							yield break;
						}
						current += 1f;
					}
					while (!(current >= duration) && depression.data.Active && !depression.isTemporaryCurePresent);
					array = doors;
					foreach (PropertyDoorController val2 in array)
					{
						if ((int)((DoorController)val2).PlayerAccess == 1 && ((DoorController)val2).noAccessErrorMessage == "You are too depressed right now")
						{
							((DoorController)val2).PlayerAccess = (EDoorAccess)0;
							((DoorController)val2).noAccessErrorMessage = "";
						}
					}
				}
				doors = null;
			}
		}
	}
	public static class AudioLoader
	{
		public static AudioClip ToAudioClip(byte[] fileBytes, string name = "wav")
		{
			int num = 0;
			int num2 = 16000;
			ushort num3 = 1;
			int dataSize = fileBytes.Length;
			bool flag = true;
			byte[] array = new byte[4];
			Array.Copy(fileBytes, 0, array, 0, 4);
			if (!Encoding.ASCII.GetString(array).Equals("RIFF"))
			{
				flag = false;
			}
			if (flag)
			{
				int num4 = BitConverter.ToInt32(fileBytes, 16);
				BitConverter.ToUInt16(fileBytes, 20);
				num3 = BitConverter.ToUInt16(fileBytes, 22);
				num2 = BitConverter.ToInt32(fileBytes, 24);
				BitConverter.ToUInt16(fileBytes, 34);
				num = 20 + num4 + 4;
				dataSize = BitConverter.ToInt32(fileBytes, num);
			}
			float[] array2 = Convert16BitByteArrayToAudioClipData(fileBytes, num, dataSize);
			AudioClip obj = AudioClip.Create(name, array2.Length / num3, (int)num3, num2, false);
			obj.SetData(Il2CppStructArray<float>.op_Implicit(array2), 0);
			return obj;
		}

		private static float[] Convert16BitByteArrayToAudioClipData(byte[] source, int headerOffset, int dataSize)
		{
			int num = dataSize;
			if (headerOffset != 0)
			{
				num = BitConverter.ToInt32(source, headerOffset);
				headerOffset += 4;
			}
			int num2 = 2;
			int num3 = num / num2;
			float[] array = new float[num3];
			short num4 = short.MaxValue;
			int num5 = 0;
			for (int i = 0; i < num3; i++)
			{
				num5 = i * num2 + headerOffset;
				array[i] = (float)BitConverter.ToInt16(source, num5) / (float)num4;
			}
			return array;
		}
	}
	[Serializable]
	public class FlatlinePlayerData
	{
		public FlatlinePlayerState State = new FlatlinePlayerState();

		public List<DiseaseData> DiseaseData = new List<DiseaseData>();

		public FlatlinePlayerData()
		{
		}

		public FlatlinePlayerData(FlatlinePlayerData original)
		{
			State = new FlatlinePlayerState(original.State);
			DiseaseData = new List<DiseaseData>();
			foreach (DiseaseData diseaseDatum in original.DiseaseData)
			{
				DiseaseData.Add(new DiseaseData(diseaseDatum));
			}
		}
	}
	[Serializable]
	public class FlatlinePlayerState
	{
		public Dictionary<string, ConsumptionData> consumptionDatas = new Dictionary<string, ConsumptionData>();

		public HealthData healthData = new HealthData();

		public float Thirst = 1f;

		public float Hunger = 1f;

		public float Energy = 1f;

		public float Temperature = 1f;

		public FlatlinePlayerState()
		{
		}

		public FlatlinePlayerState(FlatlinePlayerState original)
		{
			Thirst = original.Thirst;
			Hunger = original.Hunger;
			Energy = original.Energy;
			Temperature = original.Temperature;
			foreach (KeyValuePair<string, ConsumptionData> consumptionData in original.consumptionDatas)
			{
				consumptionDatas.Add(consumptionData.Key, new ConsumptionData(consumptionData.Value));
			}
			healthData = new HealthData(original.healthData);
		}
	}
	[Serializable]
	public class ConsumptionData
	{
		public float overtimeLungDamage;

		public float overtimeLiverDamage;

		public float currentAmountInSystem;

		public ConsumptionData()
		{
		}

		public ConsumptionData(ConsumptionData original)
		{
			overtimeLungDamage = original.overtimeLungDamage;
			overtimeLiverDamage = original.overtimeLiverDamage;
			currentAmountInSystem = original.currentAmountInSystem;
		}
	}
	[Serializable]
	public class HealthData
	{
		public float MaxHP = 100f;

		public float CurrentHP = 100f;

		public float MoveSpeedScale = 1f;

		public float Predisposition;

		public float Gluttony;

		public int TimesSmoked;

		public bool IsLegBoneBroken;

		public int daysSinceFlu;

		public HealthData()
		{
		}

		public HealthData(HealthData original)
		{
			MaxHP = original.MaxHP;
			CurrentHP = original.CurrentHP;
			MoveSpeedScale = original.MoveSpeedScale;
			Predisposition = original.Predisposition;
			Gluttony = original.Gluttony;
			TimesSmoked = original.TimesSmoked;
			IsLegBoneBroken = original.IsLegBoneBroken;
			daysSinceFlu = original.daysSinceFlu;
		}
	}
	[Serializable]
	public class DiseaseData
	{
		public string DiseaseID = "";

		public bool Active;

		public int MinsSinceDiseaseStart;

		public int Progression = 1;

		public float Severity;

		public float HealState;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public Dictionary<string, float> DiseaseStates;

		public DiseaseData()
		{
		}

		public DiseaseData(DiseaseData original)
		{
			DiseaseID = original.DiseaseID;
			Active = original.Active;
			MinsSinceDiseaseStart = original.MinsSinceDiseaseStart;
			Progression = original.Progression;
			Severity = original.Severity;
			HealState = original.HealState;
			if (original.DiseaseStates != null)
			{
				DiseaseStates = new Dictionary<string, float>(original.DiseaseStates);
			}
		}
	}
	public class FlatlineModConfig
	{
		public bool PermanentDeath = true;

		public bool DrugSideEffects = true;

		public bool PropertyTemperatureChanges = true;

		public bool WorldTemperatureChanges = true;

		public bool FahrenheitTemp;

		public bool DiseasesEnabled = true;

		public bool BleedingEnabled = true;

		public bool BoneBreakEnabled = true;

		public bool CancerEnabled = true;

		public bool DepressionEnabled = true;

		public bool FeverEnabled = true;

		public bool WaterRequired = true;

		public bool FoodRequired = true;

		public bool EnergyRequired = true;

		public bool TemperatureRequired = true;

		public float WaterConsumption = 0.00087958f;

		public float FoodConsumption = 0.0015f;

		public float EnergyConsumption = 0.0007f;

		public float TemperatureConsumption = 0.00022f;
	}
	public static class ConfigLoader
	{
		private static readonly string BASE_USERDATA_NAME = "XO_WithSauce-Flatline";

		private static readonly string TS_PACKAGE_NAME = "XO_WithSauce-Flatline_";

		private static readonly string packagePathUserData = Path.Combine(MelonEnvironment.UserDataDirectory, TS_PACKAGE_NAME + "IL2CPP", BASE_USERDATA_NAME);

		private static readonly string manualPathUserData = Path.Combine(MelonEnvironment.UserDataDirectory, BASE_USERDATA_NAME);

		private static readonly string pathPlayerData = Path.Combine(packagePathUserData, "PlayerData");

		private static readonly string pathModImageResources = Path.Combine(packagePathUserData, "ModResources", "Images");

		private static readonly string pathModAudioResources = Path.Combine(packagePathUserData, "ModResources", "Audio");

		private static readonly string pathManualPlayerData = Path.Combine(manualPathUserData, "PlayerData");

		private static readonly string pathManualModImageResources = Path.Combine(manualPathUserData, "ModResources", "Images");

		private static readonly string pathManualModAudioResources = Path.Combine(manualPathUserData, "ModResources", "Audio");

		public static readonly List<string> imageResources = new List<string> { "bleed", "bonebreak", "cancer", "depression", "energy", "fever", "meat", "temperature", "water" };

		public static readonly List<string> audioResources = new List<string> { "malecough", "malesneeze", "femalecough", "femalesneeze", "bonebreak", "flatline", "singleheartbeat" };

		public static object playerDataLock = new object();

		public static Dictionary<string, Sprite> loadedSprites = new Dictionary<string, Sprite>();

		public static Dictionary<string, AudioClip> loadedAudios = new Dictionary<string, AudioClip>();

		public static FlatlinePlayerData LoadPlayerData()
		{
			string organisationName = Singleton<LoadManager>.Instance.ActiveSaveInfo.OrganisationName;
			int saveSlotNumber = Singleton<LoadManager>.Instance.ActiveSaveInfo.SaveSlotNumber;
			string path = $"{saveSlotNumber}_{SanitizeAndFormatName(organisationName)}";
			string text = "";
			if (Directory.Exists(pathPlayerData))
			{
				text = pathPlayerData;
			}
			else
			{
				if (!Directory.Exists(pathManualPlayerData))
				{
					MelonLogger.Error("Failed to locate Flatline PlayerData from the UserData folder!");
					return null;
				}
				text = pathManualPlayerData;
			}
			FlatlinePlayerData flatlinePlayerData;
			if (File.Exists(Path.Combine(text, path)))
			{
				try
				{
					flatlinePlayerData = JsonConvert.DeserializeObject<FlatlinePlayerData>(File.ReadAllText(Path.Combine(text, path)));
				}
				catch (Exception ex)
				{
					flatlinePlayerData = new FlatlinePlayerData();
					MelonLogger.Warning("Failed to read flatline player data: " + ex);
				}
			}
			else
			{
				flatlinePlayerData = new FlatlinePlayerData();
				flatlinePlayerData.State.healthData.Predisposition = Random.Range(0.0005f, 0.02f);
				Save(flatlinePlayerData);
			}
			return flatlinePlayerData;
		}

		public static void Save(FlatlinePlayerData playerData)
		{
			lock (playerDataLock)
			{
				FlatlinePlayerData flatlinePlayerData = new FlatlinePlayerData(playerData);
				try
				{
					string organisationName = Singleton<LoadManager>.Instance.ActiveSaveInfo.OrganisationName;
					int saveSlotNumber = Singleton<LoadManager>.Instance.ActiveSaveInfo.SaveSlotNumber;
					string path = $"{saveSlotNumber}_{SanitizeAndFormatName(organisationName)}";
					string text = "";
					text = (Directory.Exists(pathPlayerData) ? pathPlayerData : ((!Directory.Exists(pathManualPlayerData)) ? pathPlayerData : pathManualPlayerData));
					string path2 = Path.Combine(text, path);
					string contents = JsonConvert.SerializeObject((object)flatlinePlayerData, (Formatting)1);
					Directory.CreateDirectory(Path.GetDirectoryName(path2));
					File.WriteAllText(path2, contents);
				}
				catch (Exception ex)
				{
					MelonLogger.Warning("Failed to save Flatline player data: " + ex);
				}
			}
		}

		public static void RemoveSaveAssociatedData(string orgName, int slotNum)
		{
			string path = $"{slotNum}_{SanitizeAndFormatName(orgName)}";
			string text = "";
			if (Directory.Exists(pathPlayerData))
			{
				text = pathPlayerData;
			}
			else
			{
				if (!Directory.Exists(pathManualPlayerData))
				{
					MelonLogger.Error("Failed to locate Flatline PlayerData from the UserData folder!");
					return;
				}
				text = pathManualPlayerData;
			}
			if (File.Exists(Path.Combine(text, path)))
			{
				try
				{
					File.Delete(Path.Combine(text, path));
				}
				catch (Exception ex)
				{
					MelonLogger.Warning("Failed to remove save associated flatline player data: " + ex);
				}
			}
		}

		public static void LoadModResources()
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00bc: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			string text = "";
			string text2 = "";
			if (Directory.Exists(packagePathUserData))
			{
				text = pathModImageResources;
				text2 = pathModAudioResources;
			}
			else
			{
				if (!Directory.Exists(manualPathUserData))
				{
					MelonLogger.Error("Failed to locate Flatline mod resources from UserData!");
					return;
				}
				text = pathManualModImageResources;
				text2 = pathManualModAudioResources;
			}
			if (Directory.Exists(text))
			{
				foreach (string imageResource in imageResources)
				{
					string path = Path.Combine(text, imageResource + ".png");
					if (File.Exists(path))
					{
						byte[] array = File.ReadAllBytes(path);
						Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
						((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x34);
						ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(array));
						((Object)val).name = imageResource;
						((Texture)val).anisoLevel = 1;
						val.Apply();
						Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f);
						((Object)val2).hideFlags = (HideFlags)(((Object)val2).hideFlags | 0x34);
						loadedSprites.Add(imageResource, val2);
					}
					else
					{
						MelonLogger.Error("Flatline mod expected to find file '" + imageResource + "' but it's missing!");
					}
				}
			}
			else
			{
				MelonLogger.Error("Flatline mod expected to find directory '" + text + "' but it's missing!");
			}
			if (Directory.Exists(text2))
			{
				foreach (string audioResource in audioResources)
				{
					string path2 = Path.Combine(text2, audioResource + ".wav");
					if (File.Exists(path2))
					{
						AudioClip val3 = AudioLoader.ToAudioClip(File.ReadAllBytes(path2));
						((Object)val3).hideFlags = (HideFlags)(((Object)val3).hideFlags | 0x34);
						loadedAudios.Add(audioResource, val3);
					}
					else
					{
						MelonLogger.Error("Flatline mod expected to find file '" + audioResource + "' but it's missing!");
					}
				}
				return;
			}
			MelonLogger.Error("Flatline mod expected to find directory '" + text2 + "' but it's missing!");
		}

		public static string SanitizeAndFormatName(string orgName)
		{
			string text = orgName;
			if (text != null)
			{
				text = text.Replace(" ", "_").ToLower();
				text = text.Replace(",", "");
				text = text.Replace(".", "");
				text = text.Replace("<", "");
				text = text.Replace(">", "");
				text = text.Replace(":", "");
				text = text.Replace("\"", "");
				text = text.Replace("/", "");
				text = text.Replace("\\", "");
				text = text.Replace("|", "");
				text = text.Replace("?", "");
				text = text.Replace("*", "");
			}
			return text + ".json";
		}
	}
	public class Bleeding : Disease
	{
		public static readonly float passiveDiseaseHealingMax = 0.0055f;

		public static readonly float passiveDiseaseHealingMin = 0.0001f;

		public float MaximumMaxHPReduction = 100f;

		private float maxHPReduced;

		public Bleeding(DiseaseData data)
		{
			base.data = data;
			base.data.DiseaseID = "bleed";
			base.minsRequiredForProgression = 240;
			onDiseaseStarted = BleedingStarted;
			MaximumMaxHPReduction = Mathf.Lerp(40f, 150f, base.data.Severity / 0.3f);
			if (base.data.DiseaseStates == null)
			{
				base.data.DiseaseStates = new Dictionary<string, float>();
			}
			if (base.data.DiseaseStates.ContainsKey("maxHPReduced"))
			{
				maxHPReduced = base.data.DiseaseStates["maxHPReduced"];
			}
			else
			{
				base.data.DiseaseStates.Add("maxHPReduced", 0f);
			}
		}

		private void BleedingStarted()
		{
			PlayerDiseaseDamage.isBleedingStemmed = false;
			if (!PlayerDiseaseDamage.bleedPressureIntObj.activeSelf)
			{
				PlayerDiseaseDamage.bleedPressureIntObj.SetActive(true);
			}
			Flatline.coros.Add(MelonCoroutines.Start(RunBleedDamage()));
		}

		private IEnumerator RunBleedDamage()
		{
			while (true)
			{
				float num;
				if (data.Progression >= 3)
				{
					yield return Flatline.Wait05;
					num = 0.5f;
				}
				else
				{
					yield return Flatline.Wait1;
					num = 1f;
				}
				if (!Flatline.registered || !data.Active || data.Progression >= 5)
				{
					break;
				}
				if (Flatline.haltExecution || Flatline.isSaving || FlatlinePlayer.isPassedOut || NetworkSingleton<TimeManager>.Instance.IsSleepInProgress)
				{
					continue;
				}
				if (FlatlinePlayer.isQueuedForDeath || maxHPReduced >= MaximumMaxHPReduction)
				{
					break;
				}
				if (data.HealState > 0.9f || PlayerDiseaseDamage.isBleedingStemmed)
				{
					continue;
				}
				float num2 = (float)base.minsRequiredForProgression * (1f + data.Severity);
				float num3 = num2 * 5f / 1440f;
				float num4 = num2 * 1f / 1440f;
				float num5 = num3 - num4;
				float num6 = MaximumMaxHPReduction / 1440f * num5 / num;
				float num7 = Mathf.Lerp(Mathf.Approximately(data.HealState, 0f) ? 0.015f : data.HealState, 0.001f, (float)data.Progression / 5f - 0.2f);
				num6 = Mathf.Clamp01(Mathf.Lerp(num6, 0f, num7)) * (float)data.Progression;
				DebugModule.Log("Calc bleed reduction: " + num6, "RunBleedDamage");
				if (Random.Range(0f, 1f) > 0.33f)
				{
					Player.Local.Health.PlayBloodMist();
				}
				if (Flatline.loadedPlayerData.State.healthData.MaxHP - num6 < Flatline.loadedPlayerData.State.healthData.CurrentHP)
				{
					float num8 = Flatline.loadedPlayerData.State.healthData.CurrentHP - (Flatline.loadedPlayerData.State.healthData.MaxHP - num6);
					if (Player.Local.Health.CurrentHealth - num8 <= 0f)
					{
						FlatlineUIModule.causeOfDeath = "Bleeding";
					}
					Player.Local.Health.TakeDamage(num8, Random.Range(0, 10) == 0, false);
					FlatlinePlayer.AppendDamageSource($"Bleeding damage (-{num8}HP)");
				}
				else
				{
					DebugModule.Log("Bleed amount not smaller than current hp", "RunBleedDamage");
				}
				maxHPReduced += num6;
				Flatline.loadedPlayerData.State.healthData.MaxHP = Mathf.Clamp(Flatline.loadedPlayerData.State.healthData.MaxHP - num6, 0f, 100f);
			}
		}

		public override void DiseaseEffect()
		{
			float num = data.MinsSinceDiseaseStart;
			if (!PlayerDiseaseDamage.bleedPressureIntObj.activeSelf)
			{
				PlayerDiseaseDamage.bleedPressureIntObj.SetActive(true);
			}
			if (PlayerDiseaseDamage.isBleedingStemmed)
			{
				num *= 0.33f;
			}
			if (Mathf.Round(num * (1f + data.Severity)) / (float)base.minsRequiredForProgression >= (float)data.Progression)
			{
				data.Progression++;
			}
			if (data.Progression >= 5 && maxHPReduced >= MaximumMaxHPReduction && !PlayerDiseaseDamage.isBleedingStemmed)
			{
				DebugModule.Log("Player died of bleeding", "DiseaseEffect");
				FlatlineUIModule.causeOfDeath = "Bleeding";
				Flatline.coros.Add(MelonCoroutines.Start(FlatlinePlayer.PrePlayerDied()));
				data.Active = false;
				return;
			}
			if (data.Progression >= 4 && Flatline.loadedPlayerData.State.Thirst > 0.15f)
			{
				Flatline.loadedPlayerData.State.Thirst -= 0.0015f;
			}
			data.HealState += Random.Range(passiveDiseaseHealingMin, passiveDiseaseHealingMax);
			if (maxHPReduced >= MaximumMaxHPReduction)
			{
				data.HealState += Random.Range(passiveDiseaseHealingMin * 3f, passiveDiseaseHealingMax * 3f);
			}
			float num2 = Mathf.Lerp(12f, 50f, Mathf.Clamp01(data.HealState));
			float num3 = Mathf.Lerp(1f, 3f, Mathf.Clamp01((float)data.Progression / 5f));
			if (PlayerDiseaseDamage.isBleedingStemmed)
			{
				data.HealState += passiveDiseaseHealingMax * num2;
				DebugModule.Log($"Stem heal: {data.HealState} +{passiveDiseaseHealingMax * num2}", "DiseaseEffect");
			}
			else
			{
				data.HealState = Mathf.Clamp01(data.HealState - passiveDiseaseHealingMax * num3);
				DebugModule.Log($"No stem: {data.HealState} -{passiveDiseaseHealingMax * num3}", "DiseaseEffect");
			}
			DebugModule.Log("Bleeding Max HP reduction total so far: " + maxHPReduced, "DiseaseEffect");
		}

		public override void DiseaseHealed()
		{
			if (PlayerDiseaseDamage.bleedPressureIntObj.activeSelf)
			{
				PlayerDiseaseDamage.bleedPressureIntObj.SetActive(false);
			}
			PlayerDiseaseDamage.isBleedingStemmed = false;
			DebugModule.Log("Healed bleeding succesfully", "DiseaseHealed");
		}

		public override void UpdateDiseaseData()
		{
			if (data.DiseaseStates == null)
			{
				data.DiseaseStates = new Dictionary<string, float>();
			}
			if (data.DiseaseStates.ContainsKey("maxHPReduced"))
			{
				data.DiseaseStates["maxHPReduced"] = maxHPReduced;
			}
			else
			{
				data.DiseaseStates.Add("maxHPReduced", maxHPReduced);
			}
		}
	}
	public class BoneBreak : Disease
	{
		public static readonly float passiveDiseaseHealingMax = 0.001f;

		public static readonly float passiveDiseaseHealingMin = 0.0001f;

		public static readonly float healingReductionWhileSprinting = 0.008f;

		public static readonly float baseMoveSpeedReduction = 0.03f;

		public static readonly float minMoveSpeedScaleValue = 0.65f;

		private bool hasDisabledJump;

		public BoneBreak(DiseaseData data)
		{
			base.data = data;
			base.data.DiseaseID = "bonebreak";
			base.minsRequiredForProgression = 4320;
		}

		public override void DiseaseEffect()
		{
			if (Mathf.Round((float)data.MinsSinceDiseaseStart * (1f + data.Severity)) / (float)base.minsRequiredForProgression >= (float)data.Progression)
			{
				data.Progression++;
			}
			if (data.Progression >= 5)
			{
				DebugModule.Log("Player died of a broken bone", "DiseaseEffect");
				FlatlineUIModule.causeOfDeath = "Broken bone";
				Flatline.coros.Add(MelonCoroutines.Start(FlatlinePlayer.PrePlayerDied()));
				data.Active = false;
				return;
			}
			data.HealState += Random.Range(passiveDiseaseHealingMin, passiveDiseaseHealingMax);
			if (PlayerSingleton<PlayerMovement>.Instance.IsSprinting)
			{
				data.HealState = Mathf.Clamp01(data.HealState - healingReductionWhileSprinting * (float)data.Progression);
			}
			if (BedRotSimulator.isBedrotting)
			{
				data.HealState += Random.Range(passiveDiseaseHealingMin, passiveDiseaseHealingMax);
			}
			if (data.Progression >= 1)
			{
				float num = Mathf.Lerp(minMoveSpeedScaleValue, 1f, data.HealState);
				if (Flatline.loadedPlayerData.State.healthData.MoveSpeedScale > num)
				{
					float num2 = Mathf.Lerp(baseMoveSpeedReduction * (float)data.Progression * (1f + data.Severity), 0f, data.HealState);
					float moveSpeedScale = Mathf.Clamp(Flatline.loadedPlayerData.State.healthData.MoveSpeedScale - num2, minMoveSpeedScaleValue, 1f);
					Flatline.loadedPlayerData.State.healthData.MoveSpeedScale = moveSpeedScale;
				}
			}
			if (data.Progression < 3 || !(data.HealState < 0.5f) || !Flatline.loadedPlayerData.State.healthData.IsLegBoneBroken)
			{
				return;
			}
			if (PlayerSingleton<PlayerMovement>.Instance.CanJump && !hasDisabledJump)
			{
				if (Random.Range(0f, 1f) > 0.95f)
				{
					PlayerSingleton<PlayerMovement>.Instance.CanJump = false;
					hasDisabledJump = true;
				}
			}
			else if (!PlayerSingleton<PlayerMovement>.Instance.CanJump && hasDisabledJump)
			{
				PlayerSingleton<PlayerMovement>.Instance.CanJump = true;
				hasDisabledJump = false;
			}
		}

		public override void DiseaseHealed()
		{
			Flatline.loadedPlayerData.State.healthData.IsLegBoneBroken = false;
			DebugModule.Log("Healed bone break succesfully", "DiseaseHealed");
		}

		public override void UpdateDiseaseData()
		{
		}
	}
	public class Cancer : Disease
	{
		public static readonly float MaximumMaxHPReduction = 100f;

		public Cancer(DiseaseData data)
		{
			base.data = data;
			base.data.DiseaseID = "cancer";
			base.minsRequiredForProgression = 10080;
		}

		public override void DiseaseEffect()
		{
			float num = Mathf.Round((float)data.MinsSinceDiseaseStart * (1f + data.Severity));
			float num2 = (float)base.minsRequiredForProgression * (1f + data.Severity);
			if (num / (float)base.minsRequiredForProgression >= (float)data.Progression)
			{
				data.Progression++;
			}
			if (data.Progression >= 5)
			{
				DebugModule.Log("Player died of cancer", "DiseaseEffect");
				FlatlineUIModule.causeOfDeath = "Cancer";
				Flatline.coros.Add(MelonCoroutines.Start(FlatlinePlayer.PrePlayerDied()));
				data.Active = false;
				return;
			}
			if (data.Progression >= 3)
			{
				float num3 = num2 * 5f / 1440f;
				float num4 = num2 * 3f / 1440f;
				float num5 = num3 - num4;
				float num6 = MaximumMaxHPReduction / 1440f * num5 / 10f;
				DebugModule.Log("Cancer Max HP reduction: " + num6, "DiseaseEffect");
				if (Flatline.loadedPlayerData.State.healthData.MaxHP - num6 < Flatline.loadedPlayerData.State.healthData.CurrentHP)
				{
					float num7 = Flatline.loadedPlayerData.State.healthData.CurrentHP - (Flatline.loadedPlayerData.State.healthData.MaxHP - num6);
					if (Player.Local.Health.CurrentHealth - num7 <= 0f)
					{
						FlatlineUIModule.causeOfDeath = "Cancer";
					}
					Player.Local.Health.TakeDamage(num7, true, false);
					FlatlinePlayer.AppendDamageSource($"Cancer damage (-{num7}HP)");
				}
				Flatline.loadedPlayerData.State.healthData.MaxHP = Mathf.Clamp(Flatline.loadedPlayerData.State.healthData.MaxHP - num6, 0f, 100f);
			}
			if (!FlatlinePlayer.flatlinePlayerAudio.isPlaying)
			{
				AudioClip val = null;
				val = ((Player.Local.Avatar.CurrentSettings.Gender > 0.5f) ? ((!(Random.Range(0f, 1f) > 0.5f)) ? ConfigLoader.loadedAudios["femalesneeze"] : ConfigLoader.loadedAudios["femalecough"]) : ((!(Random.Range(0f, 1f) > 0.5f)) ? ConfigLoader.loadedAudios["malesneeze"] : ConfigLoader.loadedAudios["malecough"]));
				if (data.Progression == 2 && Random.Range(0f, 1f) > 0.99f)
				{
					FlatlinePlayer.flatlinePlayerAudio.PlayOneShot(val);
				}
				else if (data.Progression >= 3 && Random.Range(0f, 1f) > 0.95f)
				{
					FlatlinePlayer.flatlinePlayerAudio.PlayOneShot(val);
				}
			}
		}

		public override void DiseaseHealed()
		{
			DebugModule.Log("Healed cancer succesfully", "DiseaseHealed");
		}

		public override void UpdateDiseaseData()
		{
		}
	}
	public class Depression : Disease
	{
		public static readonly float passiveDiseaseHealingMax = 0.0025f;

		public static readonly float passiveDiseaseHealingMin = 0.0001f;

		public static readonly float baseEnergyConsumptionIncrease = 0.002f;

		public static readonly float baseFoodConsumptionIncrease = 0.0008f;

		public static readonly int maxTemporaryCureMins = 120;

		public static readonly float maxBlandEffectDuration = 180f;

		public static readonly float minBlandEffectDuration = 80f;

		public static readonly float maxDisablerEffectDuration = 120f;

		public static readonly float minDisablerEffectDuration = 50f;

		private static int minsSpentBedrotting = 0;

		public bool isTemporaryCurePresent;

		private int minsSinceTemporaryCureStarted;

		public static readonly List<string> temporaryDepressionCures = new List<string> { "weed", "shroom", "cocaine", "meth" };

		public Depression(DiseaseData data)
		{
			base.data = data;
			base.data.DiseaseID = "depression";
			base.minsRequiredForProgression = 4320;
			onDiseaseStarted = RunDepressionCoros;
		}

		private void RunDepressionCoros()
		{
			Flatline.coros.Add(MelonCoroutines.Start(DepressionSimulator.DepressionBlandWorld(this)));
			Flatline.coros.Add(MelonCoroutines.Start(DepressionSimulator.DepressionDoorDisabler(this)));
			Flatline.coros.Add(MelonCoroutines.Start(DepressionSimulator.DepressionMessagerDisabler(this)));
		}

		public override void DiseaseEffect()
		{
			if (Mathf.Round((float)data.MinsSinceDiseaseStart * (1f + data.Severity)) / (float)base.minsRequiredForProgression >= (float)data.Progression)
			{
				data.Progression++;
			}
			if (data.Progression >= 5)
			{
				DebugModule.Log("Player died of depression", "DiseaseEffect");
				FlatlineUIModule.causeOfDeath = "Depression";
				Flatline.coros.Add(MelonCoroutines.Start(FlatlinePlayer.PrePlayerDied()));
				data.Active = false;
				return;
			}
			if (BedRotSimulator.isBedrotting)
			{
				minsSpentBedrotting += 10;
				float num = Mathf.Lerp(0f, 1f, Mathf.Clamp01((float)minsSpentBedrotting / 1440f));
				if (num > data.HealState)
				{
					data.HealState = num;
				}
				else
				{
					data.HealState += num / 10f;
				}
			}
			data.HealState += Random.Range(passiveDiseaseHealingMin, passiveDiseaseHealingMax);
			if (isTemporaryCurePresent)
			{
				minsSinceTemporaryCureStarted += 10;
				if (minsSinceTemporaryCureStarted >= maxTemporaryCureMins)
				{
					isTemporaryCurePresent = false;
				}
			}
			if (Flatline.loadedPlayerData.State.healthData.TimesSmoked > 0 && Flatline.loadedPlayerData.State.consumptionDatas.Count > 0)
			{
				Dictionary<string, ConsumptionData> dictionary = new Dictionary<string, ConsumptionData>(Flatline.loadedPlayerData.State.consumptionDatas);
				float num2 = 0f;
				int num3 = 0;
				foreach (KeyValuePair<string, ConsumptionData> item in dictionary)
				{
					if (temporaryDepressionCures.Contains(item.Key))
					{
						num2 += item.Value.currentAmountInSystem;
						if (num2 > 0.15f && !isTemporaryCurePresent)
						{
							isTemporaryCurePresent = true;
							minsSinceTemporaryCureStarted = 0;
						}
						num3++;
					}
				}
				if (num3 > 0)
				{
					num2 = Mathf.Clamp01(num2 / (float)num3);
					float num4 = passiveDiseaseHealingMax * (1f + num2);
					float num5 = Random.Range(passiveDiseaseHealingMin * (1f + num2), num4);
					num5 = Mathf.Lerp(num5, num4, num2);
					data.HealState += Mathf.Clamp(num5, 0f, 0.01f);
				}
			}
			if (!BedRotSimulator.isBedrotting)
			{
				float num6 = Mathf.Lerp(3f, 5f, (float)data.Progression / 5f - 0.2f);
				float num7 = Mathf.Clamp(baseEnergyConsumptionIncrease * (float)data.Progression * (1f + data.Severity), 0f, 0.01f);
				float num8 = Mathf.Clamp(baseFoodConsumptionIncrease * (float)data.Progression * (1f + data.Severity), 0f, 0.0052f);
				FlatlinePlayer.EnergyConsumptionPerMinute = Mathf.Lerp(FlatlinePlayer.EnergyConsumptionPerMinute, FlatlinePlayer.EnergyConsumptionPerMinute + num7, MaximumSystematicPropertyChangePerTick * num6);
				FlatlinePlayer.FoodConsumptionPerMinute = Mathf.Lerp(FlatlinePlayer.FoodConsumptionPerMinute, FlatlinePlayer.FoodConsumptionPerMinute + num8, MaximumSystematicPropertyChangePerTick * num6);
			}
		}

		public override void DiseaseHealed()
		{
			if (FlatlinePlayer.FoodConsumptionPerMinute > FlatlinePlayer.DefaultFoodConsumption)
			{
				FlatlinePlayer.FoodConsumptionPerMinute = Mathf.Lerp(FlatlinePlayer.FoodConsumptionPerMinute, FlatlinePlayer.DefaultFoodConsumption, 0.5f);
			}
			if (FlatlinePlayer.EnergyConsumptionPerMinute > FlatlinePlayer.DefaultEnergyConsumption)
			{
				FlatlinePlayer.EnergyConsumptionPerMinute = Mathf.Lerp(FlatlinePlayer.EnergyConsumptionPerMinute, FlatlinePlayer.DefaultEnergyConsumption, 0.5f);
			}
			DebugModule.Log("Healed depression succesfully", "DiseaseHealed");
		}

		public override void UpdateDiseaseData()
		{
		}
	}
	public class Fever : Disease
	{
		public static readonly float baseEnergyConsumptionIncrease = 7E-05f;

		public static readonly float baseTemperatureConsumptionIncrease = 0.00025f;

		public static readonly float baseThirstConsumptionIncrease = 0.00012f;

		public static readonly float passiveDiseaseHealingMax = 0.0055f;

		public static readonly float passiveDiseaseHealingMin = 0.0003f;

		public static readonly float MaximumMaxHPReduction = 33f;

		private int minsSinceLastFeverShiver;

		private int minsUntilNextFeverShiver = 120;

		public Fever(DiseaseData data)
		{
			base.data = data;
			base.data.DiseaseID = "fever";
			base.minsRequiredForProgression = 1080;
			onDiseaseStarted = FeverStarted;
		}

		private void FeverStarted()
		{
			Player.Local.Avatar.Effects.SetSicklySkinColor(true);
			Player.Local.Avatar.EmotionManager.AddEmotionOverride("Concerned", "Sickly", 0f, 5);
		}

		public override void DiseaseEffect()
		{
			minsSinceLastFeverShiver += 10;
			DebugModule.Log("Mins until next fever jitter " + (minsUntilNextFeverShiver - minsSinceLastFeverShiver), "DiseaseEffect");
			float num = Mathf.Round((float)data.MinsSinceDiseaseStart * (1f + data.Severity));
			float num2 = (float)base.minsRequiredForProgression * (1f + data.Severity);
			if (num / (float)base.minsRequiredForProgression >= (float)data.Progression)
			{
				data.Progression++;
			}
			if (data.Progression >= 5)
			{
				DebugModule.Log("Player died of fever", "DiseaseEffect");
				FlatlineUIModule.causeOfDeath = "Fever";
				Flatline.coros.Add(MelonCoroutines.Start(FlatlinePlayer.PrePlayerDied()));
				data.Active = false;
				return;
			}
			data.HealState += Random.Range(passiveDiseaseHealingMin, passiveDiseaseHealingMax);
			if (BedRotSimulator.isBedrotting)
			{
				data.HealState += Random.Range(passiveDiseaseHealingMin * 5f, passiveDiseaseHealingMax * 5f);
			}
			if (PlayerSingleton<PlayerMovement>.Instance.IsSprinting)
			{
				data.HealState = Mathf.Clamp01(data.HealState - Random.Range(passiveDiseaseHealingMin, passiveDiseaseHealingMax * 2f));
			}
			if (!FlatlinePlayer.flatlinePlayerAudio.isPlaying)
			{
				AudioClip val = null;
				val = ((Player.Local.Avatar.CurrentSettings.Gender > 0.5f) ? ((!(Random.Range(0f, 1f) > 0.5f)) ? ConfigLoader.loadedAudios["femalesneeze"] : ConfigLoader.loadedAudios["femalecough"]) : ((!(Random.Range(0f, 1f) > 0.5f)) ? ConfigLoader.loadedAudios["malesneeze"] : ConfigLoader.loadedAudios["malecough"]));
				if (data.Progression == 1 && Random.Range(0f, 1f) > 0.96f)
				{
					FlatlinePlayer.flatlinePlayerAudio.PlayOneShot(val);
				}
				else if (data.Progression == 2 && Random.Range(0f, 1f) > 0.94f)
				{
					FlatlinePlayer.flatlinePlayerAudio.PlayOneShot(val);
				}
				else if (data.Progression == 3 && Random.Range(0f, 1f) > 0.92f)
				{
					FlatlinePlayer.flatlinePlayerAudio.PlayOneShot(val);
				}
				else if (data.Progression >= 4 && Random.Range(0f, 1f) > 0.87f)
				{
					FlatlinePlayer.flatlinePlayerAudio.PlayOneShot(val);
				}
			}
			if (data.Progression >= 1)
			{
				float num3 = Mathf.Clamp(FlatlinePlayer.EnergyConsumptionPerMinute + Mathf.Clamp(baseEnergyConsumptionIncrease * (float)data.Progression * (1f + data.Severity), 0f, 0.0009f), 0f, FlatlinePlayer.DefaultEnergyConsumption * 3f);
				FlatlinePlayer.EnergyConsumptionPerMinute = Mathf.Lerp(FlatlinePlayer.EnergyConsumptionPerMinute, num3, MaximumSystematicPropertyChangePerTick * 2f);
				float num4 = Mathf.Clamp(FlatlinePlayer.TemperatureConsumption + Mathf.Clamp(baseTemperatureConsumptionIncrease * (float)data.Progression * (1f + data.Severity), 0f, 0.0015f), 0f, FlatlinePlayer.TemperatureConsumptionPerMinutePerDegreeDiff * 3f);
				FlatlinePlayer.TemperatureConsumption = Mathf.Lerp(FlatlinePlayer.TemperatureConsumption, num4, MaximumSystematicPropertyChangePerTick * 3f);
				float num5 = Mathf.Clamp(FlatlinePlayer.ThirstConsumptionPerMinute + Mathf.Clamp(baseThirstConsumptionIncrease * (float)data.Progression * (1f + data.Severity), 0f, 0.0015f), 0f, FlatlinePlayer.DefaultThirstConsumption * 3f);
				FlatlinePlayer.ThirstConsumptionPerMinute = Mathf.Lerp(FlatlinePlayer.ThirstConsumptionPerMinute, num5, MaximumSystematicPropertyChangePerTick * 3f);
			}
			if (data.Progression >= 2 && data.HealState < 0.8f && Flatline.loadedPlayerData.State.healthData.MaxHP > 100f - MaximumMaxHPReduction)
			{
				float num6 = num2 * 5f / 1440f;
				float num7 = num2 * 2f / 1440f;
				float num8 = num6 - num7;
				float num9 = MaximumMaxHPReduction / 1440f * num8 / 10f;
				num9 = Mathf.Clamp01(Mathf.Lerp(num9, 0f, data.HealState));
				DebugModule.Log("Fever Max HP reduction: " + num9, "DiseaseEffect");
				if (Flatline.loadedPlayerData.State.healthData.MaxHP - num9 < Flatline.loadedPlayerData.State.healthData.CurrentHP)
				{
					float num10 = Flatline.loadedPlayerData.State.healthData.CurrentHP - (Flatline.loadedPlayerData.State.healthData.MaxHP - num9);
					if (Player.Local.Health.CurrentHealth - num10 <= 0f)
					{
						FlatlineUIModule.causeOfDeath = "Fever";
					}
					Player.Local.Health.TakeDamage(num10, false, false);
					FlatlinePlayer.AppendDamageSource($"Fever damage (-{num10}HP)");
				}
				Flatline.loadedPlayerData.State.healthData.MaxHP = Mathf.Clamp(Flatline.loadedPlayerData.State.healthData.MaxHP - num9, 10f, 100f);
			}
			if (minsSinceLastFeverShiver >= minsUntilNextFeverShiver)
			{
				Flatline.coros.Add(MelonCoroutines.Start(BlurShort()));
				minsSinceLastFeverShiver = 0;
				switch (data.Progression)
				{
				case 1:
					minsUntilNextFeverShiver = Random.Range(100, 200);
					break;
				case 2:
					minsUntilNextFeverShiver = Random.Range(80, 180);
					break;
				case 3:
					minsUntilNextFeverShiver = Random.Range(70, 120);
					break;
				case 4:
					minsUntilNextFeverShiver = Random.Range(50, 100);
					break;
				default:
					minsUntilNextFeverShiver = Random.Range(80, 360);
					break;
				}
			}
		}

		public IEnumerator BlurShort()
		{
			if (!Flatline.registered || FlatlinePlayer.isPassedOut || FlatlinePlayer.isQueuedForDeath)
			{
				yield break;
			}
			DebugModule.Log("Start blur", "BlurShort");
			Mathf.Lerp(2f, 5f, (float)data.Progression / 5f);
			PlayerSingleton<PlayerCamera>.Instance.FoVChangeSmoother.AddOverride(-8f, 5, "fever");
			PlayerSingleton<PlayerCamera>.Instance.SmoothLookSmoother.AddOverride(0.8f, 5, "fever");
			if (data.Progression > 3)
			{
				Player.Local.Disoriented = true;
			}
			Player.Local.Seizure = true;
			Singleton<PostProcessingManager>.Instance.SetBlur(1f);
			yield return Flatline.Wait5;
			if (Flatline.registered)
			{
				Player.Local.Seizure = false;
				if (data.Progression > 3 && Player.Local.Disoriented)
				{
					Player.Local.Disoriented = false;
				}
				Singleton<PostProcessingManager>.Instance.SetBlur(0f);
				PlayerSingleton<PlayerCamera>.Instance.FoVChangeSmoother.RemoveOverride("fever");
				PlayerSingleton<PlayerCamera>.Instance.SmoothLookSmoother.RemoveOverride("fever");
				DebugModule.Log("End blur", "BlurShort");
			}
		}

		public override void DiseaseHealed()
		{
			if (FlatlinePlayer.EnergyConsumptionPerMinute > FlatlinePlayer.DefaultEnergyConsumption)
			{
				FlatlinePlayer.EnergyConsumptionPerMinute = Mathf.Lerp(FlatlinePlayer.EnergyConsumptionPerMinute, FlatlinePlayer.DefaultFoodConsumption, 0.5f);
			}
			if (FlatlinePlayer.ThirstConsumptionPerMinute > FlatlinePlayer.DefaultThirstConsumption)
			{
				FlatlinePlayer.ThirstConsumptionPerMinute = Mathf.Lerp(FlatlinePlayer.ThirstConsumptionPerMinute, FlatlinePlayer.DefaultThirstConsumption, 0.5f);
			}
			if (FlatlinePlayer.TemperatureConsumption > FlatlinePlayer.TemperatureConsumptionPerMinutePerDegreeDiff)
			{
				FlatlinePlayer.TemperatureConsumption = Mathf.Lerp(FlatlinePlayer.TemperatureConsumption, FlatlinePlayer.TemperatureConsumptionPerMinutePerDegreeDiff, 0.5f);
			}
			Player.Local.Avatar.Effects.SetSicklySkinColor(false);
			Player.Local.Avatar.EmotionManager.RemoveEmotionOverride("Sickly");
			DebugModule.Log("Healed fever succesfully", "DiseaseHealed");
		}

		public override void UpdateDiseaseData()
		{
		}
	}
	public abstract class Disease
	{
		public readonly float ParasympatheticHealing = 0.0002f;

		public readonly float MaximumSystematicPropertyChangePerTick = 1f / 144f;

		public DiseaseData data;

		public object diseaseCoroutine;

		public Action onDiseaseStarted;

		public int minsRequiredForProgression { get; set; }

		public abstract void DiseaseEffect();

		public abstract void DiseaseHealed();

		public abstract void UpdateDiseaseData();

		public IEnumerator DiseaseEvaluator()
		{
			FlatlineUIModule.diseaseIcons[data.DiseaseID].SetActive(true);
			if (onDiseaseStarted != null)
			{
				onDiseaseStarted();
			}
			while (data.Active)
			{
				yield return Flatline.Wait10;
				if (FlatlinePlayer.isQueuedForDeath && !Flatline.currentConfig.PermanentDeath && Player.PlayerList.Count > 1)
				{
					continue;
				}
				if (!Flatline.registered || FlatlinePlayer.isQueuedForDeath)
				{
					yield break;
				}
				if (!Flatline.isSaving && !FlatlinePlayer.isPassedOut && !NetworkSingleton<TimeManager>.Instance.IsSleepInProgress && !Flatline.haltExecution && (Player.PlayerList.Count <= 1 || Player.Local.Health.IsAlive) && (NetworkSingleton<TimeManager>.Instance.CurrentTime >= 659 || NetworkSingleton<TimeManager>.Instance.CurrentTime <= 400))
				{
					if (data.DiseaseID != "cancer" && Flatline.loadedPlayerData.State.Hunger > 0.9f)
					{
						data.HealState += ParasympatheticHealing;
					}
					if (data.HealState >= 1f)
					{
						break;
					}
					if (HospitalHealing.hospitalChoiceInitialized)
					{
						UpdateChoiceState((NPC)(object)HospitalHealing.lisaNPC, HospitalHealing.lisaCureChoices);
						UpdateChoiceState((NPC)(object)HospitalHealing.ireneNPC, HospitalHealing.ireneCureChoices);
					}
					data.MinsSinceDiseaseStart += 10;
					DiseaseEffect();
				}
			}
			data.Active = false;
			FlatlineUIModule.diseaseIcons[data.DiseaseID].SetActive(false);
			DiseaseHealed();
			if (HospitalHealing.hospitalChoiceInitialized)
			{
				UpdateChoiceState((NPC)(object)HospitalHealing.lisaNPC, HospitalHealing.lisaCureChoices);
				UpdateChoiceState((NPC)(object)HospitalHealing.ireneNPC, HospitalHealing.ireneCureChoices);
			}
			diseaseCoroutine = null;
		}

		private void UpdateChoiceState(NPC npc, Dictionary<string, DialogueChoice> choices)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)npc != (Object)null && choices.TryGetValue(data.DiseaseID, out var value))
			{
				value.Enabled = Vector3.Distance(npc.CenterPoint, HospitalHealing.hospitalDoorPoint) <= 7f && data.Active && data.HealState < 1f;
			}
		}
	}
	public static class PlayerConsumeDamage
	{
		public enum EConsumeType
		{
			None,
			Weed,
			Meth,
			Cocaine,
			Shroom,
			Paracetamol,
			Addy,
			Chili
		}

		public static readonly List<string> trackedKeys = new List<string> { "cocaine", "meth", "shroom", "weed", "paracetamol", "addy", "chili" };

		public static readonly int CocaineLifeTimeHrs = 8;

		public static readonly float cocaineSystemicAmountPerDose = 0.08f;

		public static readonly float cocaineConsumeLungDamage = 0.004f;

		public static readonly int MethLifeTimeHrs = 12;

		public static readonly float methSystemicAmountPerDose = 0.11f;

		public static readonly float methConsumeLungDamage = 0.0005f;

		public static readonly int ShroomsLifeTimeHrs = 6;

		public static readonly float shroomSystemicAmountPerDose = 0.06f;

		public static readonly float weedConsumeLungDamage = 0.009f;

		public static readonly float paracetamolLiverDamage = 0.005f;

		public static readonly int ParacetamolLifeTimeHrs = 18;

		public static readonly int AddyLifeTimeHrs = 14;

		public static readonly int ChiliLifeTimeHrs = 50;

		public static readonly Dictionary<string, int> lifeTimeHours = new Dictionary<string, int>
		{
			{ "cocaine", CocaineLifeTimeHrs },
			{ "meth", MethLifeTimeHrs },
			{ "shroom", ShroomsLifeTimeHrs },
			{ "paracetamol", ParacetamolLifeTimeHrs },
			{ "addy", AddyLifeTimeHrs },
			{ "chili", ChiliLifeTimeHrs }
		};

		public static bool ProductEffectRunning = false;

		public static bool IsWeedEffectRunning = false;

		public static bool IsShroomEffectRunning = false;

		public static bool IsMethEffectRunning = false;

		public static bool IsCocaineEffectRunning = false;

		public static AudioSource heartBeatSource = null;

		public static bool heartPumpOverrideActive = false;

		public static void InitConsumeDamageModule()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("FlatlineHeartAudio");
			val.transform.parent = ((Component)PlayerSingleton<PlayerCamera>.Instance).transform;
			val.transform.localPosition = Vector3.zero;
			heartBeatSource = val.AddComponent<AudioSource>();
			heartBeatSource.volume = 0.7f;
			heartBeatSource.loop = false;
			val.SetActive(true);
			((Behaviour)heartBeatSource).enabled = true;
		}

		public static void ResetConsumeDamageModule()
		{
			ProductEffectRunning = false;
			IsWeedEffectRunning = false;
			IsShroomEffectRunning = false;
			IsMethEffectRunning = false;
			IsCocaineEffectRunning = false;
			heartBeatSource = null;
			heartPumpOverrideActive = false;
		}

		public static EConsumeType TypeFromID(string id)
		{
			return id switch
			{
				"weed" => EConsumeType.Weed, 
				"meth" => EConsumeType.Meth, 
				"cocaine" => EConsumeType.Cocaine, 
				"shroom" => EConsumeType.Shroom, 
				"paracetamol" => EConsumeType.Paracetamol, 
				"addy" => EConsumeType.Addy, 
				"chili" => EConsumeType.Chili, 
				_ => EConsumeType.None, 
			};
		}

		public static void OnProductConsumed(EConsumeType type, EQuality quality = (EQuality)0, bool useQuality = false)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (!Flatline.currentConfig.DrugSideEffects || type == EConsumeType.None)
			{
				return;
			}
			float num = 1f;
			float num2 = 1f;
			if (useQuality)
			{
				int num3 = Enum.GetNames(typeof(EQuality)).Length - 1;
				num = Mathf.Lerp(1f, 2f, (float)quality / (float)num3);
				num2 = Mathf.Lerp(2f, 1f, (float)quality / (float)num3);
				Flatline.coros.Add(MelonCoroutines.Start(WaitRandomAfterConsume(type, quality)));
			}
			string key = type.ToString().ToLower();
			if (!Flatline.loadedPlayerData.State.consumptionDatas.ContainsKey(key))
			{
				Flatline.loadedPlayerData.State.consumptionDatas.Add(key, new ConsumptionData());
			}
			switch (type)
			{
			case EConsumeType.Weed:
				Flatline.loadedPlayerData.State.consumptionDatas[key].overtimeLungDamage += weedConsumeLungDamage * num2;
				Flatline.loadedPlayerData.State.healthData.TimesSmoked++;
				break;
			case EConsumeType.Meth:
				Flatline.loadedPlayerData.State.consumptionDatas[key].overtimeLungDamage += methConsumeLungDamage * num2;
				Flatline.loadedPlayerData.State.consumptionDatas[key].currentAmountInSystem += methSystemicAmountPerDose * num;
				Flatline.loadedPlayerData.State.healthData.TimesSmoked++;
				Flatline.coros.Add(MelonCoroutines.Start(CurrentProductMonitor()));
				Flatline.coros.Add(MelonCoroutines.Start(StimulantEffectChanger()));
				Flatline.coros.Add(MelonCoroutines.Start(HeartPumpOverride("meth")));
				break;
			case EConsumeType.Cocaine:
				Flatline.loadedPlayerData.State.consumptionDatas[key].overtimeLungDamage += cocaineConsumeLungDamage * num2;
				Flatline.loadedPlayerData.State.consumptionDatas[key].currentAmountInSystem += cocaineSystemicAmountPerDose * num;
				Flatline.coros.Add(MelonCoroutines.Start(CurrentProductMonitor()));
				Flatline.coros.Add(MelonCoroutines.Start(StimulantEffectChanger()));
				Flatline.coros.Add(MelonCoroutines.Start(HeartPumpOverride("cocaine")));
				break;
			case EConsumeType.Shroom:
				Flatline.loadedPlayerData.State.consumptionDatas[key].currentAmountInSystem += shroomSystemicAmountPerDose * num;
				Flatline.coros.Add(MelonCoroutines.Start(CurrentProductMonitor()));
				Flatline.coros.Add(MelonCoroutines.Start(ShroomEffectChanger()));
				break;
			case EConsumeType.Paracetamol:
			{
				Flatline.loadedPlayerData.State.consumptionDatas[key].currentAmountInSystem += IngestibleParacetamol.SystemicAmountPerDose;
				Flatline.loadedPlayerData.State.consumptionDatas[key].overtimeLiverDamage += paracetamolLiverDamage;
				float maxHP = Flatline.loadedPlayerData.State.healthData.MaxHP;
				if (!Mathf.Approximately(maxHP, 100f))
				{
					Flatline.loadedPlayerData.State.healthData.MaxHP = Mathf.Clamp(maxHP + IngestibleParacetamol.MaxHPRegen, 1f, 100f);
				}
				break;
			}
			case EConsumeType.Addy:
				Flatline.loadedPlayerData.State.consumptionDatas[key].currentAmountInSystem += IngestibleAddy.SystemicAmountPerDose;
				break;
			case EConsumeType.Chili:
				Flatline.loadedPlayerData.State.consumptionDatas[key].currentAmountInSystem += IngestibleChili.SystemicAmountPerDose;
				break;
			}
			DebugModule.Log("Changed consumption values succesfully", "OnProductConsumed");
		}

		public static IEnumerator WaitRandomAfterConsume(EConsumeType type, EQuality quality)
		{
			//IL_000e: 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)
			int randomWaitMins = Random.Range(3, 6);
			for (int i = 0; i < randomWaitMins; i++)
			{
				yield return Flatline.Wait60;
				if (!Flatline.registered || FlatlinePlayer.isQueuedForDeath || Flatline.haltExecution)
				{
					yield break;
				}
			}
			if (Flatline.isSaving)
			{
				yield return (object)new WaitUntil(Func<bool>.op_Implicit((Func<bool>)(() => !Flatline.isSaving)));
			}
			if (!Flatline.registered || FlatlinePlayer.isQueuedForDeath || Flatline.haltExecution)
			{
				yield break;
			}
			DebugModule.Log("Evaluate after effects for drug", "WaitRandomAfterConsume");
			if ((type == EConsumeType.Meth || type == EConsumeType.Cocaine) && (int)quality < 4 && Random.Range(0f, 1f) > 0.8f)
			{
				Player.Local.Avatar.Effects.TriggerSick(false);
				if (Flatline.loadedPlayerData.State.Hunger > 0.1f)
				{
					FlatlinePlayer.SetFood(Mathf.Clamp01(Flatline.loadedPlayerData.State.Hunger * 0.95f));
				}
				if (Flatline.loadedPlayerData.State.Thirst > 0.1f)
				{
					FlatlinePlayer.SetWater(Mathf.Clamp01(Flatline.loadedPlayerData.State.Thirst * 0.92f));
				}
			}
			else if (type == EConsumeType.Weed && (int)quality >= 2 && Random.Range(0f, 1f) > 0.2f)
			{
				if (Flatline.loadedPlayerData.State.Hunger > 0.1f)
				{
					FlatlinePlayer.SetFood(Mathf.Clamp01(Flatline.loadedPlayerData.State.Hunger * 0.75f));
				}
				if (Flatline.loadedPlayerData.State.Thirst > 0.1f)
				{
					FlatlinePlayer.SetWater(Mathf.Clamp01(Flatline.loadedPlayerData.State.Thirst * 0.75f));
				}
			}
			PlayerDiseaseDamage.CalculateDepressionAfterConsumeProbability(type, quality);
		}

		public static void OnHourPass()
		{
			if (Flatline.registered && !FlatlinePlayer.isQueuedForDeath && !Flatline.haltExecution && (NetworkSingleton<TimeManager>.Instance.CurrentTime >= 659 || NetworkSingleton<TimeManager>.Instance.CurrentTime <= 400))
			{
				Flatline.coros.Add(MelonCoroutines.Start(SystemicDecay()));
			}
		}

		public static IEnumerator SystemicDecay()
		{
			if (Flatline.isSaving)
			{
				yield return (object)new WaitUntil(Func<bool>.op_Implicit((Func<bool>)(() => !Flatline.isSaving)));
			}
			foreach (string item in new List<string>(Flatline.loadedPlayerData.State.consumptionDatas.Keys))
			{
				float currentAmountInSystem = Flatline.loadedPlayerData.State.consumptionDatas[item].currentAmountInSystem;
				if (currentAmountInSystem > 0f)
				{
					int lifeTimeHrs = lifeTimeHours[item];
					float num = DecayHalfLife(currentAmountInSystem, lifeTimeHrs);
					if (num < 0.0001f)
					{
						num = 0f;
					}
					Flatline.loadedPlayerData.State.consumptionDatas[item].currentAmountInSystem = num;
				}
			}
			if (Flatline.loadedPlayerData.State.consumptionDatas.Any((KeyValuePair<string, ConsumptionData> x) => x.Value.currentAmountInSystem >= 1f))
			{
				KeyValuePair<string, ConsumptionData> keyValuePair = Flatline.loadedPlayerData.State.consumptionDatas.First((KeyValuePair<string, ConsumptionData> x) => x.Value.currentAmountInSystem >= 1f);
				DebugModule.Log("Player consumed lethal dose of: " + keyValuePair.Key, "SystemicDecay");
				FlatlineUIModule.causeOfDeath = "Lethal dose of " + keyValuePair.Key;
				Player.Local.Avatar.Effects.TriggerSick(false);
				Flatline.coros.Add(MelonCoroutines.Start(FlatlinePlayer.PrePlayerDied()));
				if (Player.PlayerList.Count > 1)
				{
					Flatline.loadedPlayerData.State.consumptionDatas[keyValuePair.Key].currentAmountInSystem = 0f;
				}
			}
			else if (Flatline.loadedPlayerData.State.consumptionDatas.Any((KeyValuePair<string, ConsumptionData> x) => x.Value.overtimeLiverDamage >= 1f))
			{
				KeyValuePair<string, ConsumptionData> keyValuePair2 = Flatline.loadedPlayerData.State.consumptionDatas.First((KeyValuePair<string, ConsumptionData> x) => x.Value.overtimeLiverDamage >= 1f);
				DebugModule.Log("Players liver failed due to: " + keyValuePair2.Key, "SystemicDecay");
				FlatlineUIModule.causeOfDeath = "Liver failure from consumption of " + keyValuePair2.Key;
				Player.Local.Avatar.Effects.TriggerSick(false);
				Flatline.coros.Add(MelonCoroutines.Start(FlatlinePlayer.PrePlayerDied()));
				if (Player.PlayerList.Count > 1)
				{
					Flatline.loadedPlayerData.State.consumptionDatas[keyValuePair2.Key].overtimeLiverDamage = 0f;
				}
			}
			else if (Flatline.loadedPlayerData.State.consumptionDatas.Any((KeyValuePair<string, ConsumptionData> x) => x.Value.overtimeLungDamage >= 1f))
			{
				KeyValuePair<string, ConsumptionData> keyValuePair3 = Flatline.loadedPlayerData.State.consumptionDatas.First((KeyValuePair<string, ConsumptionData> x) => x.Value.overtimeLungDamage >= 1f);
				DebugModule.Log("Players lungs failed due to: " + keyValuePair3.Key, "SystemicDecay");
				FlatlineUIModule.causeOfDeath = "Pulmonary embolism from smoking " + keyValuePair3.Key;
				Player.Local.Avatar.Effects.TriggerSick(false);
				Flatline.coros.Add(MelonCoroutines.Start(FlatlinePlayer.PrePlayerDied()));
				if (Player.PlayerList.Count > 1)
				{
					Flatline.loadedPlayerData.State.consumptionDatas[keyValuePair3.Key].overtimeLungDamage = 0f;
				}
			}
		}

		public static float DecayHalfLife(float current, int lifeTimeHrs)
		{
			return Mathf.Clamp(current * Mathf.Pow(0.5f, 1f / (float)lifeTimeHrs), 0f, 2f);
		}

		public static IEnumerator CurrentProductMonitor()
		{
			if (ProductEffectRunning)
			{
				yield break;
			}
			ProductEffectRunning = true;
			yield return Flatline.Wait025;
			ProductItemInstance current = Player.Local.ConsumedProduct;
			if (current != null)
			{
				yield return (object)new WaitUntil(Func<bool>.op_Implicit((Func<bool>)(() => CanContinue())));
			}
			DebugModule.Log("Current product has ended, disable", "CurrentProductMonitor");
			ProductEffectRunning = false;
			IsWeedEffectRunning = false;
			IsShroomEffectRunning = false;
			IsMethEffectRunning = false;
			IsCocaineEffectRunning = false;
			bool CanContinue()
			{
				if (Flatline.registered && !FlatlinePlayer.isQueuedForDeath && Player.Local.ConsumedProduct != null && Player.Local.ConsumedProduct == current)
				{
					return Flatline.haltExecution;
				}
				return true;
			}
		}

		public static IEnumerator ShroomEffectChanger()
		{
			if (IsShroomEffectRunning)
			{
				yield break;
			}
			IsShroomEffectRunning = true;
			float amplitudeMax = 0.5f;
			float amplitudeMin = 0.19f;
			float blendMax = 0.4f;
			float blendMin = 0.016f;
			float noiseScaleMax = 50f;
			float noiseScaleMin = 15f;
			float num = 0f;
			if (Flatline.loadedPlayerData.State.consumptionDatas.TryGetValue("shroom", out var value))
			{
				num = Mathf.Clamp01(value.currentAmountInSystem);
			}
			float targetAmp = Mathf.Lerp(amplitudeMin, amplitudeMax, num) * Random.Range(0.95f, 1.05f);
			float targetBld = Mathf.Lerp(blendMin, blendMax, num) * Random.Range(0.95f, 1.05f);
			float targetNoi = Mathf.Lerp(noiseScaleMin, noiseScaleMax, num) * Random.Range(0.95f, 1.05f);
			MaterialProperties activeProperties = Singleton<PostProcessingManager>.Instance.GetActivePsychedelicEffectProperties();
			MaterialProperties source = activeProperties.Clone();
			PsychedelicFullScreenData psychedelicEffectDataPreset = Singleton<PostProcessingManager>.Instance.GetPsychedelicEffectDataPreset("Active");
			MaterialProperties targetMaterialProperties = psychedelicEffectDataPreset.ConvertToMaterialProperties();
			targetMaterialProperties.Blend = targetBld;
			targetMaterialProperties.NoiseScale = targetNoi;
			targetMaterialProperties.Amplitude = targetAmp;
			Singleton<EnvironmentFX>.Instance.SetEnvironmentScrollingActive(true);
			Singleton<PostProcessingManager>.Instance.SetPsychedelicEffectActive(true);
			float easeInTime = 2f;
			float currentEase = 0f;
			while (currentEase < easeInTime)
			{
				if (!Flatline.registered)
				{
					yield break;
				}
				currentEase += Time.deltaTime;
				float num2 = currentEase / easeInTime;
				activeProperties.Blend = Mathf.Lerp(source.Blend, targetMaterialProperties.Blend, num2);
				Singleton<EnvironmentFX>.Instance.SetEnvironmentScrollingSpeedByPercentage(Mathf.Lerp(0f, 1f, num2));
				yield return null;
			}
			Singleton<PostProcessingManager>.Instance.SetPsychedelicEffectProperties(targetMaterialProperties);
			float sleepTime = 5f;
			float sleepCurrent = 0f;
			bool shouldBreak = false;
			while (!shouldBreak)
			{
				while (sleepCurrent < sleepTime)
				{
					sleepCurrent += Time.deltaTime;
					if (!Flatline.registered)
					{
						yield break;
					}
					if (!ProductEffectRunning || !IsShroomEffectRunning)
					{
						shouldBreak = true;
						break;
					}
					yield return null;
				}
				sleepCurrent = 0f;
				if (shouldBreak)
				{
					break;
				}
				if (Flatline.isSaving || !Flatline.loadedPlayerData.State.consumptionDatas.TryGetValue("shroom", out var value2))
				{
					continue;
				}
				float num3 = Mathf.Clamp01(value2.currentAmountInSystem);
				if (num3 > 0.75f && Random.Range(0f, 1f) > 0.98f)
				{
					Player.Local.Avatar.Effects.TriggerSick(false);
					FlatlinePlayer.SetFood(Mathf.Clamp01(Flatline.loadedPlayerData.State.Hunger - 0.05f));
					FlatlinePlayer.SetWater(Mathf.Clamp01(Flatline.loadedPlayerData.State.Thirst - 0.02f));
				}
				targetAmp = Mathf.Lerp(amplitudeMin, amplitudeMax, num3);
				targetBld = Mathf.Lerp(blendMin, blendMax, num3);
				targetNoi = Mathf.Lerp(noiseScaleMin, noiseScaleMax, num3);
				MaterialProperties temp = Singleton<PostProcessingManager>.Instance.GetActivePsychedelicEffectProperties().Clone();
				targetAmp = Mathf.Clamp(targetAmp, temp.Amplitude - amplitudeMax / 10f, temp.Amplitude + amplitudeMax / 10f);
				targetBld = Mathf.Clamp(targetBld, temp.Blend - blendMax / 10f, temp.Blend + blendMax / 10f);
				targetNoi = Mathf.Clamp(targetNoi, temp.NoiseScale - noiseScaleMax / 10f, temp.NoiseScale + noiseScaleMax / 10f);
				float num4 = Random.Range(0f, 1f);
				float num5 = Random.Range(0f, 1f);
				float num6 = Random.Range(0f, 1f);
				bool useBlend = false;
				bool useNoise = false;
				bool useAmplitude = false;
				List<int> list = new List<int> { 0, 1, 2 };
				int num7 = list.Count;
				while (num7 > 1)
				{
					num7--;
					int index = Random.Range(0, num7 + 1);
					int value3 = list[index];
					list[index] = list[num7];
					list[num7] = value3;
				}
				for (int i = 0; i < 2; i++)
				{
					if (list[i] == 0 && (double)num4 > 0.33)
					{
						useBlend = true;
					}
					if (list[i] == 1 && (double)num5 > 0.33)
					{
						useNoise = true;
					}
					if (list[i] == 2 && (double)num6 > 0.33)
					{
						useAmplitude = true;
					}
				}
				if (!(useBlend || useNoise || useAmplitude))
				{
					continue;
				}
				currentEase = 0f;
				while (currentEase < easeInTime)
				{
					if (!Flatline.registered)
					{
						yield break;
					}
					if (!ProductEffectRunning || !IsShroomEffectRunning)
					{
						shouldBreak = true;
						break;
					}
					currentEase += Time.deltaTime;
					float num8 = currentEase / easeInTime;
					float num9 = Mathf.SmoothStep(0f, 1f, num8);
					if (useBlend)
					{
						activeProperties.Blend = Mathf.Lerp(temp.Blend, targetBld, num9);
					}
					if (useNoise)
					{
						activeProperties.NoiseScale = Mathf.Lerp(temp.NoiseScale, targetNoi, num9);
					}
					if (useAmplitude)
					{
						activeProperties.Amplitude = Mathf.Lerp(temp.Amplitude, targetAmp, num9);
					}
					yield return null;
				}
				if (shouldBreak)
				{
					break;
				}
				targetMaterialProperties = activeProperties.Clone();
				Singleton<PostProcessingManager>.Instance.SetPsychedelicEffectProperties(targetMaterialProperties);
				sleepTime = Random.Range(5f, 10f);
				easeInTime = Random.Range(2f, 6f);
			}
			DebugModule.Log("Shroom effect changer ended", "ShroomEffectChanger");
			IsShroomEffectRunning = false;
		}

		public static IEnumerator StimulantEffectChanger()
		{
			if (IsCocaineEffectRunning || IsMethEffectRunning)
			{
				yield break;
			}
			IsCocaineEffectRunning = true;
			IsMethEffectRunning = true;
			yield return Flatline.Wait2;
			if (!Flatline.registered)
			{
				yield break;
			}
			float sleepTime = 2f;
			float sleepCurrent = 0f;
			bool shouldBreak = false;
			while (!shouldBreak)
			{
				while (sleepCurrent < sleepTime)
				{
					sleepCurrent += Time.deltaTime;
					if (!Flatline.registered)
					{
						yield break;
					}
					if (!ProductEffectRunning || !IsMethEffectRunning || !IsCocaineEffectRunning)
					{
						shouldBreak = true;
						break;
					}
					yield return null;
				}
				sleepCurrent = 0f;
				if (shouldBreak)
				{
					break;
				}
				float num = 0f;
				if (Flatline.loadedPlayerData.State.consumptionDatas.TryGetValue("meth", out var value) && value.currentAmountInSystem > 0.001f)
				{
					num = value.currentAmountInSystem;
				}
				if (Flatline.loadedPlayerData.State.consumptionDatas.TryGetValue("cocaine", out var value2) && value2.currentAmountInSystem > 0.001f && value2.currentAmountInSystem > num)
				{
					num = value2.currentAmountInSystem;
				}
				num = Mathf.Clamp01(num);
				if (num > 0.75f && Random.Range(0f, 1f) > 0.98f)
				{
					Player.Local.Avatar.Effects.TriggerSick(false);
					FlatlinePlayer.SetFood(Mathf.Clamp01(Flatline.loadedPlayerData.State.Hunger - 0.05f));
					FlatlinePlayer.SetWater(Mathf.Clamp01(Flatline.loadedPlayerData.State.Thirst - 0.02f));
				}
				float num2 = Mathf.Lerp(0.9f, 0.75f, num);
				if (Random.Range(0f, 1f) < num2)
				{
					continue;
				}
				float num3 = Mathf.Lerp(1.15f, 2f, num);
				float rotAmount = Random.Range(2f, 6f) * num3;
				rotAmount = ((Random.Range(0, 2) == 0) ? (0f - rotAmount) : rotAmount);
				for (int i = 0; i < Random.Range(4, 8); i++)
				{
					yield return Flatline.Wait05;
					if (!Flatline.registered)
					{
						yield break;
					}
					if (!ProductEffectRunning || !IsMethEffectRunning || !IsCocaineEffectRunning)
					{
						shouldBreak = true;
						break;
					}
					if (Random.Range(0f, 1f) > 0.55f)
					{
						float num4 = 0.5f;
						float num5 = 0f;
						Quaternion rotation = ((Component)Player.Local).transform.root.rotation;
						while (num5 < num4)
						{
							if (!Flatline.registered)
							{
								yield break;
							}
							if (!ProductEffectRunning || !IsMethEffectRunning || !IsCocaineEffectRunning)
							{
								shouldBreak = true;
								break;
							}
							num5 += Time.deltaTime;
							float num6 = num5 / num4;
							((Component)Player.Local).transform.root.rotation = Quaternion.Lerp(rotation, Quaternion.Euler(0f, rotation.y + rotAmount, 0f), num6);
						}
						if (shouldBreak)
						{
							break;
						}
					}
					if (i % 2 != 0)
					{
						continue;
					}
					PlayerInventory instance = PlayerSingleton<PlayerInventory>.Instance;
					if (GameInput.IsTyping || Singleton<PauseMenu>.Instance.IsPaused || !instance.HotbarEnabled)
					{
						continue;
					}
					int num7 = Random.Range(0, 8);
					if (num7 != instance.EquippedSlotIndex)
					{
						if (instance.EquippedSlotIndex != -1)
						{
							instance.IndexAllSlots(instance.EquippedSlotIndex).Unequip();
						}
						instance.PreviousEquippedSlotIndex = instance.EquippedSlotIndex;
						instance.EquippedSlotIndex = num7;
						instance.Equip(instance.IndexAllSlots(num7));
						PlayerSingleton<ViewmodelSway>.Instance.RefreshViewmodel();
					}
				}
				if (shouldBreak)
				{
					break;
				}
			}
			IsCocaineEffectRunning = false;
			IsMethEffectRunning = false;
			DebugModule.Log("Stimulant effect changer ended", "StimulantEffectChanger");
		}

		public static IEnumerator HeartPumpOverride(string consumedID)
		{
			if (heartPumpOverrideActive)
			{
				yield break;
			}
			heartPumpOverrideActive = true;
			DebugModule.Log("Starting heart pump override", "HeartPumpOverride");
			if (!Flatline.loadedPlayerData.State.consumptionDatas.TryGetValue(consumedID, out var data))
			{
				DebugModule.Log("No match for id in consumption data", "HeartPumpOverride");
				heartPumpOverrideActive = false;
				yield break;
			}
			if (!CanContinue(data))
			{
				heartPumpOverrideActive = false;
				yield break;
			}
			float maxTotalElapsed = 120f;
			float totalElapsed = 0f;
			int maxBeatsPerMinute = 200;
			int minBeatsPerMinute = 70;
			int num = Mathf.RoundToInt(Mathf.Lerp((float)minBeatsPerMinute, (float)maxBeatsPerMinute, Mathf.Clamp01(data.currentAmountInSystem)));
			DebugModule.Log("Setting bpm to " + num, "HeartPumpOverride");
			float elapsedSinceLast = 0f;
			float num2 = (float)num / 60f;
			float secondsForBeat = 1f / num2;
			while (true)
			{
				if (!Flatline.registered)
				{
					yield break;
				}
				if (!CanContinue(data) || totalElapsed >= maxTotalElapsed)
				{
					break;
				}
				yield return Flatline.Wait01;
				totalElapsed += 0.1f;
				elapsedSinceLast += 0.1f;
				if (elapsedSinceLast >= secondsForBeat)
				{
					if ((Object)(object)heartBeatSource != (Object)null && !heartBeatSource.isPlaying)
					{
						heartBeatSource.PlayOneShot(ConfigLoader.loadedAudios["singleheartbeat"]);
					}
					if (Mathf.RoundToInt(totalElapsed) % 5 == 0)
					{
						num = Mathf.RoundToInt(Mathf.Lerp((float)minBeatsPerMinute, (float)maxBeatsPerMinute, Mathf.Clamp01(data.currentAmountInSystem)));
						num2 = (float)num / 60f;
						secondsForBeat = 1f / num2;
					}
				}
			}
			DebugModule.Log("Finished heart pump override", "HeartPumpOverride");
			heartPumpOverrideActive = false;
			static bool CanContinue(ConsumptionData consumptionData)
			{
				if (PlayerSingleton<PlayerCamera>.Instance.HeartbeatSoundController._sound._audioSource.volume == 0f && Mathf.Clamp01(consumptionData.currentAmountInSystem) > 0.55f && !FlatlinePlayer.isQueuedForDeath && !FlatlinePlayer.isPassedOut)
				{
					return ProductEffectRunning;
				}
				return false;
			}
		}
	}
	[HarmonyPatch(typeof(ShroomInstance), "DoPsychedlicEffectBlend")]
	public static class ShroomInstance_DoPsychedlicEffectBlend_Patch
	{
		[HarmonyPrefix]
		public static bool Prefix(ShroomInstance __instance, ref IEnumerator __result, MaterialProperties targetMaterialProperties, float targetValuePercentage, float duration)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			if (!Flatline.currentConfig.DrugSideEffects)
			{
				return true;
			}
			if (targetValuePercentage > 0f)
			{
				MonoEnumeratorWrapper val = new MonoEnumeratorWrapper(EmptyCoroutine());
				__result = ((Il2CppObjectBase)val).Cast<IEnumerator>();
				return false;
			}
			return true;
		}

		public static IEnumerator EmptyCoroutine()
		{
			yield break;
		}
	}
	public static class PlayerDiseaseDamage
	{
		private enum ImpactLocation
		{
			Legs,
			Torso,
			Head
		}

		public static List<Disease> allDiseases = new List<Disease>();

		public static readonly List<string> diseaseNames = new List<string> { "cancer", "fever", "bonebreak", "bleed", "depression" };

		public static GameObject bleedPressureIntObj;

		public static bool isBleedingStemmed = false;

		public static void InitPlayerDiseaseDamage()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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)
			bleedPressureIntObj = new GameObject("ApplyPressureInt");
			bleedPressureIntObj.layer = LayerMask.NameToLayer("Task");
			bleedPressureIntObj.transform.parent = ((Component)Player.Local).transform.root;
			bleedPressureIntObj.transform.localScale = Vector3.one;
			bleedPressureIntObj.transform.localRotation = Quaternion.identity;
			bleedPressureIntObj.transform.localPosition = new Vector3(0f, 0.1f, 0.1f);
			bleedPressureIntObj.AddComponent<BoxCollider>().size = new Vector3(0.2f, 0.2f, 0.2f);
			InteractableObject obj = bleedPressureIntObj.AddComponent<InteractableObject>();
			obj.message = "Stem bleeding";
			obj.MaxInteractionRange = 2f;
			obj.interactionType = (EInteractionType)0;
			obj.onInteractStart.AddListener(UnityAction.op_Implicit((Action)SetIsBleedingStemmedTrue));
			obj.onInteractEnd.AddListener(UnityAction.op_Implicit((Action)SetIsBleedingStemmedFalse));
			bleedPressureIntObj.SetActive(false);
			static void SetIsBleedingStemmedFalse()
			{
				DebugModule.Log("Disable bleeding stemmed", "InitPlayerDiseaseDamage");
				isBleedingStemmed = false;
			}
			static void SetIsBleedingStemmedTrue()
			{
				DebugModule.Log("Set bleeding stemmed", "InitPlayerDiseaseDamage");
				isBleedingStemmed = true;
			}
		}

		public static void ResetPlayerDiseaseDamage()
		{
			bleedPressureIntObj = null;
			isBleedingStemmed = false;
		}

		public static void ApplyLoadedDiseases()
		{
			if (!Flatline.currentConfig.DiseasesEnabled)
			{
				return;
			}
			foreach (DiseaseData diseaseDatum in Flatline.loadedPlayerData.DiseaseData)
			{
				switch (diseaseDatum.DiseaseID)
				{
				case "cancer":
				{
					Cancer item5 = new Cancer(diseaseDatum);
					allDiseases.Add(item5);
					break;
				}
				case "fever":
				{
					Fever item4 = new Fever(diseaseDatum);
					allDiseases.Add(item4);
					break;
				}
				case "bonebreak":
				{
					BoneBreak item3 = new BoneBreak(diseaseDatum);
					allDiseases.Add(item3);
					break;
				}
				case "bleed":
				{
					Bleeding item2 = new Bleeding(diseaseDatum);
					allDiseases.Add(item2);
					break;
				}
				case "depression":
				{
					Depression item = new Depression(diseaseDatum);
					allDiseases.Add(item);
					break;
				}
				default:
					DebugModule.Log("Unknown disease id: " + diseaseDatum.DiseaseID, "ApplyLoadedDiseases");
					break;
				}
			}
			bool flag = false;
			foreach (Disease allDisease in allDiseases)
			{
				if (allDisease.data.Active && allDisease.data.HealState < 1f)
				{
					allDisease.diseaseCoroutine = MelonCoroutines.Start(allDisease.DiseaseEvaluator());
				}
				if (allDisease.data.DiseaseID == "bonebreak")
				{
					flag = true;
				}
			}
			if (Flatline.loadedPlayerData.State.healthData.IsLegBoneBroken && !flag)
			{
				DebugModule.Log("Player leg bone cant be broken since there is no active disease, setting false", "ApplyLoadedDiseases");
				Flatline.loadedPlayerData.State.healthData.IsLegBoneBroken = false;
			}
		}

		public static void UpdateDiseaseData()
		{
			Flatline.loadedPlayerData.DiseaseData.Clear();
			foreach (Disease allDisease in allDiseases)
			{
				if (allDisease.data.Active)
				{
					allDisease.UpdateDiseaseData();
					Flatline.loadedPlayerData.DiseaseData.Add(allDisease.data);
				}
			}
		}

		public static T AddNewDisease<T>(float severity) where T : Disease
		{
			if (!Flatline.currentConfig.DiseasesEnabled)
			{
				return null;
			}
			if (typeof(T) == typeof(Bleeding) && !Flatline.currentConfig.BleedingEnabled)
			{
				return null;
			}
			if (typeof(T) == typeof(BoneBreak) && !Flatline.currentConfig.BoneBreakEnabled)
			{
				return null;
			}
			if (typeof(T) == typeof(Cancer) && !Flatline.currentConfig.CancerEnabled)
			{
				return null;
			}
			if (typeof(T) == typeof(Depression) && !Flatline.currentConfig.DepressionEnabled)
			{
				return null;
			}
			if (typeof(T) == typeof(Fever) && !Flatline.currentConfig.FeverEnabled)
			{
				return null;
			}
			float num = Mathf.Clamp(severity, 0f, 0.3f);
			foreach (Disease allDisease in allDiseases)
			{
				if (allDisease.GetType() == typeof(T) && allDisease.data.Active)
				{
					DebugModule.Log("Disease of type " + typeof(T).Name + " is already active, can't add duplicate", "AddNewDisease");
					if (allDisease.GetType() == typeof(Bleeding) && allDisease.data.Severity < num)
					{
						DebugModule.Log("Upgrading bleeding to worse severity on reapply", "AddNewDisease");
						allDisease.data.Severity = num;
						allDisease.data.HealState *= 0.75f;
						(allDisease as Bleeding).MaximumMaxHPReduction = Mathf.Lerp(40f, 150f, num / 0.3f);
					}
					return null;
				}
			}
			DiseaseData diseaseData = new DiseaseData();
			diseaseData.Active = true;
			diseaseData.Severity = num;
			T val = (T)Activator.CreateInstance(typeof(T), diseaseData);
			allDiseases.Add(val);
			val.diseaseCoroutine = MelonCoroutines.Start(val.DiseaseEvaluator());
			DebugModule.Log("Succesfully added new disease: " + typeof(T).Name, "AddNewDisease");
			return val;
		}

		public static void OnHourPass()
		{
			if (!Flatline.haltExecution && !NetworkSingleton<TimeManager>.Instance.IsSleepInProgress && (NetworkSingleton<TimeManager>.Instance.CurrentTime >= 659 || NetworkSingleton<TimeManager>.Instance.CurrentTime <= 400))
			{
				CalculateFeverProbability();
			}
		}

		public static void OnSleepEnd()
		{
			if (!Flatline.haltExecution)
			{
				CalculateCancerProbability();
				CalculateDepressionPassiveProbability();
			}
		}

		public static void CalculateDepressionPassiveProbability()
		{
			float num = Mathf.Clamp01((float)NetworkSingleton<TimeManager>.Instance.ElapsedDays / 100f);
			int num2 = ((FlatlinePlayer.minsInsideProperty == 0) ? 1 : FlatlinePlayer.minsInsideProperty);
			int num3 = ((FlatlinePlayer.minsOutsideProperty == 0) ? 1 : FlatlinePlayer.minsOutsideProperty);
			float num4 = 0f;
			if (num2 >= num3)
			{
				int num5 = num2 - num3;
				if ((float)num5 > 480f)
				{
					num4 += 0.09f;
				}
				else if ((float)num5 > 360f)
				{
					num4 += 0.06f;
				}
				else if ((float)num5 > 240f)
				{
					num4 += 0.03f;
				}
			}
			int num6 = 0;
			float num7 = 0f;
			if (Flatline.loadedPlayerData.State.consumptionDatas.Count > 0)
			{
				foreach (KeyValuePair<string, ConsumptionData> consumptionData in Flatline.loadedPlayerData.State.consumptionDatas)
				{
					if (Depression.temporaryDepressionCures.Contains(consumptionData.Key))
					{
						num7 += consumptionData.Value.currentAmountInSystem;
						num6++;
					}
				}
			}
			float num8 = 0f;
			if (num6 > 0)
			{
				num7 /= (float)num6;
				num8 = Mathf.Lerp(0f, 0.03f, num7);
			}
			num8 += Mathf.Clamp((float)Flatline.loadedPlayerData.State.healthData.TimesSmoked / 100f, 0f, 0.33f);
			num8 = Mathf.Clamp01(num8);
			float num9 = 0f;
			if (Flatline.loadedPlayerData.State.Thirst <= 0.65f)
			{
				num9 += 0.002f;
			}
			if (Flatline.loadedPlayerData.State.Hunger <= 0.65f)
			{
				num9 += 0.002f;
			}
			if (Flatline.loadedPlayerData.State.Temperature <= 0.65f)
			{
				num9 += 0.002f;
			}
			if (NetworkSingleton<MoneyManager>.Instance.cashBalance < 5000f)
			{
				num9 += 0.002f;
			}
			float gender = Player.Local.Avatar.CurrentSettings.Gender;
			float num10 = 0f;
			num10 = ((!(gender > 0.5f)) ? Random.Range(0.003f, 0.004f) : Random.Range(0.005f, 0.007f));
			float num11 = (float)FlatlinePlayer.minsWithSunnyWeather / 1440f;
			float num12 = Mathf.Lerp(0.25f, 0f, num11);
			float num13 = (num + num4 + num7 + num9 + num10 + num12) / 6f;
			DebugModule.Log($"Mins with sun: {FlatlinePlayer.minsWithSunnyWeather} ({num12})", "CalculateDepressionPassiveProbability");
			DebugModule.Log("Depression chance subtotal: " + num13, "CalculateDepressionPassiveProbability");
			if (Random.Range(0f, 1f) < num13)
			{
				DebugModule.Log("Depression consumption chance hits", "CalculateDepressionPassiveProbability");
				AddNewDisease<Depression>(Random.Range(0.001f, 0.3f));
			}
			FlatlinePlayer.minsOutsideProperty = 0;
			FlatlinePlayer.minsInsideProperty = 0;
			FlatlinePlayer.minsWithSunnyWeather = 0;
		}

		public static void CalculateDepressionAfterConsumeProbability(PlayerConsumeDamage.EConsumeType type, EQuality quality)
		{
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			if (type != PlayerConsumeDamage.EConsumeType.Weed && type != PlayerConsumeDamage.EConsumeType.Meth && type != PlayerConsumeDamage.EConsumeType.Cocaine && type != PlayerConsumeDamage.EConsumeType.Shroom)
			{
				return;
			}
			float num = 0f;
			switch (type)
			{
			case PlayerConsumeDamage.EConsumeType.Weed:
			{
				if (Flatline.loadedPlayerData.State.consumptionDatas.TryGetValue("weed", out var value3) && value3.currentAmountInSystem < 0.3f)
				{
					num = Random.Range(0.002f, 0.019f);
				}
				break;
			}
			case PlayerConsumeDamage.EConsumeType.Shroom:
			{
				if (Flatline.loadedPlayerData.State.consumptionDatas.TryGetValue("shroom", out var value2) && value2.currentAmountInSystem > 0.08f)
				{
					num = Random.Range(0.002f, 0.025f);
				}
				break;
			}
			case PlayerConsumeDamage.EConsumeType.Meth:
			{
				if (Flatline.loadedPlayerData.State.consumptionDatas.TryGetValue("meth", out var value4) && value4.currentAmountInSystem < 0.35f)
				{
					num = Random.Range(0.03f, 0.095f);
				}
				break;
			}
			case PlayerConsumeDamage.EConsumeType.Cocaine:
			{
				if (Flatline.loadedPlayerData.State.consumptionDatas.TryGetValue("cocaine", out var value) && value.currentAmountInSystem < 0.35f)
				{
					num = Random.Range(0.03f, 0.125f);
				}
				break;
			}
			}
			if (num == 0f)
			{
				num = 0.05f;
			}
			float num2 = num;
			float num3 = 1f + Flatline.loadedPlayerData.State.healthData.Predisposition;
			int num4 = Enum.GetNames(typeof(EQuality)).Length - 1;
			float num5 = Mathf.Lerp(0.95f, 1.08f, (float)quality / (float)num4);
			float num6 = Mathf.Clamp01(num2 * num3 * num5);
			DebugModule.Log("Depression subtotal consumption: " + num6, "CalculateDepressionAfterConsumeProbability");
			if (Random.Range(0f, 1f) < num6)
			{
				DebugModule.Log("Depression consumption chance hits", "CalculateDepressionAfterConsumeProbability");
				AddNewDisease<Depression>(Random.Range(0.001f, 0.3f));
			}
		}

		public static void CalculateFallBoneBreakProbability(float fallDamage)
		{
			float num = 0f;
			if (fallDamage >= 20f && fallDamage <= 25f)
			{
				num += 0.2f;
			}
			else if (fallDamage > 20f && fallDamage <= 28f)
			{
				num += 0.35f;
			}
			else if (fallDamage > 28f && fallDamage <= 38f)
			{
				num += 0.65f;
			}
			else if (fallDamage > 38f)
			{
				num += 0.75f;
			}
			float weight = Player.Local.Avatar.CurrentSettings.Weight;
			if (weight <= 0.25f)
			{
				num += 0.005f;
			}
			else if (weight > 0.25f && weight <= 0.4f)
			{
				num += 0.015f;
			}
			else if (weight > 0.4f && weight <= 0.65f)
			{
				num += 0.03f;
			}
			else if (weight > 0.65f)
			{
				num += 0.07f;
			}
			bool flag = false;
			bool flag2 = false;
			if (!(fallDamage <= 0.12f))
			{
				if (Player.Local.Health.CurrentHealth - fallDamage <= 0f)
				{
					FlatlineUIModule.causeOfDeath = "Fall damage";
					flag2 = true;
				}
				if (!flag2 && !FlatlinePlayer.isFPRagdollActive && !Player.Local.IsRagdolled && fallDamage > 20f)
				{
					flag = true;
					Flatline.coros.Add(MelonCoroutines.Start(FlatlinePlayer.FPRagdoll(waitSleepEnd: false, null, 0)));
				}
				Player.Local.Health.TakeDamage(fallDamage, true, false);
				FlatlinePlayer.AppendDamageSource($"Fall damage (-{Mathf.RoundToInt(fallDamage)}HP)");
			}
			if (!(fallDamage <= 0.18f) && Random.Range(0f, 1f) < num)
			{
				if (!flag && !flag2 && !FlatlinePlayer.isFPRagdollActive && !Player.Local.IsRagdolled)
				{
					Flatline.coros.Add(MelonCoroutines.Start(FlatlinePlayer.FPRagdoll(waitSleepEnd: false, null, 0)));
				}
				if (!FlatlinePlayer.flatlinePlayerAudio.isPlaying)
				{
					FlatlinePlayer.flatlinePlayerAudio.PlayOneShot(ConfigLoader.loadedAudios["bonebreak"]);
				}
				if (!flag2)
				{
					AddNewDisease<BoneBreak>(Random.Range(0.01f, 0.3f));
					Flatline.loadedPlayerData.State.healthData.IsLegBoneBroken = true;
				}
				DebugModule.Log("Fall damage bone break chance hits", "CalculateFallBoneBreakProbability");
			}
		}

		public static void CalculateImpact(Impact impact)
		{
			//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_0011: Unknown result type (might be due to invali