Decompiled source of Environmental Awareness The Trials Of Toil v1.0.7

plugins/EnvironmentalAwareness.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EnvironmentalAwareness.Data;
using HarmonyLib;
using JetBrains.Annotations;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using ServerSync;
using SkillManager;
using TMPro;
using UnityEngine;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: AssemblyProduct("EnvironmentalAwareness")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyCompany("EnvironmentalAwareness")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyTitle("EnvironmentalAwareness")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<26dcf9ab-0225-42ca-8171-42fe9c6d0527>Embedded]
	internal sealed class <26dcf9ab-0225-42ca-8171-42fe9c6d0527>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	[CompilerGenerated]
	[<26dcf9ab-0225-42ca-8171-42fe9c6d0527>Embedded]
	internal sealed class <ea518f4f-51c4-47f8-b97f-a8a02765119d>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <ea518f4f-51c4-47f8-b97f-a8a02765119d>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <ea518f4f-51c4-47f8-b97f-a8a02765119d>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	[<26dcf9ab-0225-42ca-8171-42fe9c6d0527>Embedded]
	[CompilerGenerated]
	internal sealed class <83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace EnvironmentalAwareness
{
	[BepInPlugin("maxfoxgaming.environmentalawareness", "EnvironmentalAwareness", "1.0.7")]
	[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(0)]
	[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(1)]
	public class Main : BaseUnityPlugin
	{
		public const string PluginGUID = "maxfoxgaming.environmentalawareness";

		public const string PluginName = "EnvironmentalAwareness";

		public const string PluginVersion = "1.0.7";

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		private static Main instance;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		public AssetBundle Bundle;

		public static Harmony harmony = new Harmony("maxfoxgaming.environmentalawareness");

		public static readonly string ModPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		public static ManualLogSource Log;

		public static readonly string VitalitySEName = "EA_Vitality";

		public static readonly string HungrySEName = "EA_Hungry";

		public static readonly string EnergySEName = "EA_Energy";

		public static readonly string PlayerStatsSEName = "EA_PlayerStats";

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		public SE_Vitality Vitality;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		public SE_Hungry Hungry;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		public SE_Energy Energy;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		public SE_PlayerStats PlayerStats;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		public Skill Resistance;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		public Skill Fitness;

		public TutorialText[] TutorialTexts = (TutorialText[])(object)new TutorialText[4]
		{
			new TutorialText
			{
				m_name = "EnvironmentalAwarenessVitality",
				m_label = "$ea_tutorial_vitality_label",
				m_text = "$ea_tutorial_vitality_text",
				m_topic = "$ea_tutorial_vitality_topic"
			},
			new TutorialText
			{
				m_name = "EnvironmentalAwarenessVitalityLow",
				m_label = "$ea_tutorial_vitality_low_label",
				m_text = "$ea_tutorial_vitality_low_text",
				m_topic = "$ea_tutorial_vitality_low_topic"
			},
			new TutorialText
			{
				m_name = "EnvironmentalAwarenessEnergy",
				m_label = "$ea_tutorial_energy_label",
				m_text = "$ea_tutorial_energy_text",
				m_topic = "$ea_tutorial_energy_topic"
			},
			new TutorialText
			{
				m_name = "EnvironmentalAwarenessEnergyLow",
				m_label = "$ea_tutorial_energy_low_label",
				m_text = "$ea_tutorial_energy_low_text",
				m_topic = "$ea_tutorial_energy_low_topic"
			}
		};

		private readonly string[] credits = new string[7] { "ProbablyKory: Inspiration from the StormExposure mod.", "Azumatt: Help with Valheim asset ripping and referencing.", "OrianaVenture: Encouragement with trying status effect manipulation.", "GsiX & HugoTheDwarf: Help with sprite sizes.", "Blaxxun: ServerSync, SkillManager and LocalizationManager.", "Blacks7ar: Help with SkillManager to get level of custom skill.", "love5225: Korean translations" };

		public void Awake()
		{
			Localizer.Load();
			Log = ((BaseUnityPlugin)this).Logger;
			instance = this;
			ConfigManager.CreateConfigValues((BaseUnityPlugin)(object)this);
			LogMessage("Loading");
			LogMessage("Loading bundles.");
			Bundle = LoadBundle("environmentalsprites");
			LogMessage("Initializing Status Effects.");
			Vitality = ScriptableObject.CreateInstance<SE_Vitality>();
			((Object)Vitality).name = VitalitySEName;
			Hungry = ScriptableObject.CreateInstance<SE_Hungry>();
			((Object)Hungry).name = HungrySEName;
			Energy = ScriptableObject.CreateInstance<SE_Energy>();
			((Object)Energy).name = EnergySEName;
			PlayerStats = ScriptableObject.CreateInstance<SE_PlayerStats>();
			((Object)PlayerStats).name = PlayerStatsSEName;
			LogMessage("Adding Skills.");
			Resistance = new Skill("Resistance", Bundle.LoadAsset<Sprite>("vitalityicon1"));
			Resistance.SkillEffectFactor = ConfigManager.ResistanceSkillEffectFactor.Value;
			Resistance.SkillGainFactor = ConfigManager.ResistanceSkillGainFactor.Value;
			Resistance.Configurable = false;
			Fitness = new Skill("Fitness", Bundle.LoadAsset<Sprite>("energyicon1"));
			Fitness.SkillEffectFactor = ConfigManager.FitnessSkillEffectFactor.Value;
			Fitness.SkillGainFactor = ConfigManager.FitnessSkillGainFactor.Value;
			Fitness.Configurable = false;
			Harmony val = harmony;
			if (val != null)
			{
				val.PatchAll();
			}
		}

		public void OnDestroy()
		{
			Harmony val = harmony;
			if (val != null)
			{
				val.UnpatchSelf();
			}
			instance = null;
		}

		[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(2)]
		public static Main GetInstance()
		{
			return instance;
		}

		public static void LogMessage(string message)
		{
			if (ConfigManager.DebugLogging.Value)
			{
				Log.LogMessage((object)message);
			}
		}

		[return: <ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		public static AssetBundle LoadBundle(string name)
		{
			string text = "";
			try
			{
				text = Assembly.GetExecutingAssembly().GetManifestResourceNames().Single((string str) => str.EndsWith(name));
			}
			catch (Exception)
			{
			}
			if (text == "")
			{
				LogMessage("Could not find assembly with name " + name + ".");
				return null;
			}
			AssetBundle result;
			using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text))
			{
				result = AssetBundle.LoadFromStream(stream);
			}
			LogMessage("Loaded assetbundle successfully.");
			return result;
		}
	}
	[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(0)]
	[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(1)]
	public class SE_Energy : SE_Stats
	{
		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(new byte[] { 2, 1 })]
		public Sprite[] icons;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		public Sprite iconNoSkillDrain;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		public Sprite iconNewSpawn;

		public float m_energyLoss = 0f;

		public float m_maxEnergyLoss = 100f;

		public float m_staminaRegenDelay = 0f;

		public float m_energyFromFood = 0f;

		public float m_energyFromFoodTick = 0f;

		public float m_energyRegenSpeed = 0.5f;

		public float m_energyLossPerc = 0f;

		public float m_timeSinceRested = 0f;

		public float fitnessSkillMultiplier = 1f;

		public float energyChange = 0f;

		public float updateTimerState = 0f;

		public float updateTimerStats = 0f;

		public float updateTimerIcon = 0f;

		public float updateTimerLogs = 0f;

		public float countdownTimer = 300f;

		public float seasonMultiplier = 1f;

		public float lossEnergyRestedMult = 1f;

		public float lossEnergyCarryWeightAdd = 0f;

		public float lossEnergyMovementAdd = 0f;

		public float staminaMeadMult = 1f;

		public float noRestMultiplier = 1f;

		public float totalStaminaUseInCycle = 0f;

		public float totalEnergyUseInCycle = 0f;

		public float lastRawLossInCycle;

		public bool warningSpeed;

		public bool warningStaminaRegen;

		public bool warningStaminaDelay;

		public bool warningSkillGain;

		public bool warningSkillLevel;

		public bool warningDamage;

		public bool warningWeight;

		public readonly float baseMaxEnergyLoss = 100f;

		public readonly string[] statuses = new string[5] { "$ea_energy_status_0", "$ea_energy_status_1", "$ea_energy_status_2", "$ea_energy_status_3", "$ea_energy_status_4" };

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		private Player player;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		private SE_PlayerStats pes;

		public static readonly int Hash = StringExtensionMethods.GetStableHashCode(Main.EnergySEName);

		public override void Setup(Character character)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			((SE_Stats)this).Setup(character);
			((StatusEffect)this).m_name = "$ea_se_energy";
			LoadIcons();
			((StatusEffect)this).m_icon = icons[0];
			updateTimerState = 0f;
			updateTimerStats = 0f;
			updateTimerIcon = 0f;
			updateTimerLogs = 0f;
			countdownTimer = ConfigManager.NewPlayerCooldown.Value;
			base.m_modifyAttackSkill = (SkillType)999;
			base.m_skillLevel = (SkillType)999;
			base.m_skillLevelModifier = 0f;
			base.m_raiseSkill = (SkillType)999;
			base.m_raiseSkillModifier = 0f;
			ref Player reference = ref player;
			Character character2 = ((StatusEffect)this).m_character;
			reference = (Player)(object)((character2 is Player) ? character2 : null);
			if ((Object)(object)player == (Object)null)
			{
				((StatusEffect)this).m_character.m_seman.RemoveStatusEffect((StatusEffect)(object)this, false);
				return;
			}
			if (player.IsMaterialKnown("$item_stone") || player.IsMaterialKnown("$item_wood"))
			{
				Main.LogMessage("Player knows a material. Cooldown disabled for Energy status.");
				countdownTimer = 0f;
			}
			pes = ((Character)player).m_seman.GetStatusEffect(SE_PlayerStats.Hash) as SE_PlayerStats;
			if ((Object)(object)pes == (Object)null)
			{
				((StatusEffect)this).m_character.m_seman.RemoveStatusEffect((StatusEffect)(object)this, false);
			}
			else
			{
				Recalculate();
			}
		}

		public void LoadIcons()
		{
			Sprite[] array = (Sprite[])(object)new Sprite[15];
			for (int i = 0; i < 15; i++)
			{
				string text = "energyicon" + (i + 1);
				array[i] = Main.GetInstance().Bundle.LoadAsset<Sprite>(text);
			}
			icons = array;
			iconNoSkillDrain = Main.GetInstance().Bundle.LoadAsset<Sprite>("energyicondeath");
			iconNewSpawn = Main.GetInstance().Bundle.LoadAsset<Sprite>("energyiconnewplayer");
		}

		public override void Stop()
		{
			((StatusEffect)this).Stop();
			((StatusEffect)this).m_ttl = 1f;
			m_energyLoss = 0f;
			m_maxEnergyLoss = 100f;
			m_staminaRegenDelay = 0f;
			base.m_raiseSkillModifier = 0f;
			base.m_skillLevelModifier = 0f;
			updateTimerState = 0f;
			updateTimerStats = 0f;
			updateTimerIcon = 0f;
			updateTimerLogs = 0f;
			countdownTimer = ConfigManager.NewPlayerCooldown.Value;
		}

		public override bool IsDone()
		{
			return false;
		}

		public override string GetTooltipString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (pes.PlayerNoSkillDrain)
			{
				stringBuilder.Append("$ea_player_energy_immune \n");
				return stringBuilder.ToString();
			}
			if (countdownTimer > 0f)
			{
				stringBuilder.AppendFormat("$ea_player_energy_cooldown: {0}s. \n", Mathf.Ceil(countdownTimer));
				return stringBuilder.ToString();
			}
			stringBuilder.Append(GetEnergyStatus());
			if (pes.PlayerStaminaMead)
			{
				stringBuilder.Append("$ea_player_stamina_mead \n");
			}
			if (m_energyFromFood > 0f)
			{
				stringBuilder.Append("$ea_player_food_recover_energy \n");
			}
			if (m_timeSinceRested > ConfigManager.ELossNoRestThreshold.Value / 2f)
			{
				stringBuilder.Append("$ea_player_need_rest_energy \n");
			}
			if (m_energyLossPerc > ConfigManager.ERestedLossThreshold.Value)
			{
				stringBuilder.Append("$ea_player_cannot_stay_rested \n");
			}
			if (energyChange > 0f)
			{
				if (pes.PlayerCold || pes.PlayerFreezing)
				{
					stringBuilder.Append("$ea_player_coldfreezing_energy \n");
				}
				if (pes.PlayerWet)
				{
					stringBuilder.Append("$ea_player_wet_energy \n");
				}
				if (pes.PlayerHungry)
				{
					stringBuilder.Append("$ea_player_hungry_energy \n");
				}
			}
			else if (energyChange < 0f && m_energyLoss > 0.5f)
			{
				stringBuilder.Append("$ea_player_recovering_energy \n");
			}
			stringBuilder.Append(((SE_Stats)this).GetTooltipString());
			if (m_staminaRegenDelay > 0f)
			{
				stringBuilder.AppendFormat("$ea_se_staminaregendelay: <color=orange>{0}s</color> \n", (Mathf.Floor(10f * m_staminaRegenDelay) / 10f).ToString("+0;-0"));
			}
			if (staminaMeadMult != 1f)
			{
				stringBuilder.AppendFormat("$ea_se_energylossresist: <color=green>{0}%</color> \n", Mathf.Floor(100f * staminaMeadMult));
			}
			return stringBuilder.ToString();
		}

		public string GetEnergyStatus()
		{
			int num = Mathf.Clamp(Mathf.FloorToInt(m_energyLoss / m_maxEnergyLoss * (float)statuses.Length), 0, statuses.Length - 1);
			return statuses[num] + "\n";
		}

		public override string GetIconText()
		{
			if (pes.PlayerNoSkillDrain)
			{
				return "";
			}
			if (countdownTimer > 0f)
			{
				return StatusEffect.GetTimeString(countdownTimer, false, false);
			}
			if (!ConfigManager.DisplayEnergyPercentage.Value)
			{
				return "";
			}
			int num = 100 - Mathf.FloorToInt(100f * (m_energyLoss / m_maxEnergyLoss));
			return $"{num}%";
		}

		public override void UpdateStatusEffect(float dt)
		{
			if ((Object)(object)pes == (Object)null)
			{
				((StatusEffect)this).m_character.m_seman.RemoveStatusEffect((StatusEffect)(object)this, false);
			}
			((SE_Stats)this).UpdateStatusEffect(dt);
			if (countdownTimer <= 0f && !pes.PlayerNoSkillDrain)
			{
				UpdateStaminaRegenDelay();
				UpdateEnergyFromFood(dt);
			}
			m_energyLossPerc = 100f * (m_energyLoss / m_maxEnergyLoss);
			if (countdownTimer <= 0f && !pes.PlayerNoSkillDrain)
			{
				updateTimerState += dt;
				updateTimerStats += dt;
			}
			updateTimerIcon += dt;
			updateTimerLogs += dt;
			if (!((Object)(object)player == (Object)null))
			{
				if (updateTimerState >= 1f && countdownTimer <= 0f && !pes.PlayerNoSkillDrain)
				{
					UpdateNonRestedState();
					UpdateMovementState();
					UpdateEnergyValue();
					updateTimerState -= 1f;
				}
				if (updateTimerStats >= 5f && countdownTimer <= 0f && !pes.PlayerNoSkillDrain)
				{
					UpdateEffects();
					UpdateTutorial();
					updateTimerStats -= 5f;
				}
				if (updateTimerLogs >= 10f)
				{
					LogStatistics();
					ResetCycleStats();
					updateTimerLogs -= 10f;
				}
				if (countdownTimer > 0f)
				{
					countdownTimer -= dt;
				}
				else
				{
					countdownTimer = 0f;
				}
				if (updateTimerIcon > 1f)
				{
					UpdateIcon();
					updateTimerIcon -= 1f;
				}
			}
		}

		public void UpdateTutorial()
		{
			if (m_energyLossPerc > 10f)
			{
				player.ShowTutorial("EnvironmentalAwarenessEnergy", false);
			}
			if (m_energyLossPerc > 60f)
			{
				player.ShowTutorial("EnvironmentalAwarenessEnergyLow", false);
			}
		}

		public void UpdateStaminaRegenDelay()
		{
			if (!((Object)(object)pes == (Object)null))
			{
				player.m_staminaRegenDelay = pes.PlayerStaminaRegenDelay + m_staminaRegenDelay;
			}
		}

		public void UpdateEnergyFromFood(float dt)
		{
			if ((double)m_energyFromFood < 0.01)
			{
				m_energyFromFood = 0f;
				m_energyFromFoodTick = 0f;
				return;
			}
			m_energyFromFoodTick = m_maxEnergyLoss / baseMaxEnergyLoss * Mathf.Min(m_energyRegenSpeed, m_energyFromFood) * dt;
			Main.LogMessage("Energy tick: " + m_energyFromFoodTick);
			m_energyLoss -= m_energyFromFoodTick;
			if (m_energyLoss < 0f)
			{
				m_energyLoss = 0f;
			}
			m_energyFromFood -= m_energyFromFoodTick;
		}

		public void UpdateNonRestedState()
		{
			if (pes.PlayerRested)
			{
				m_timeSinceRested = 0f;
				noRestMultiplier = 1f;
			}
			else
			{
				m_timeSinceRested += 1f;
				noRestMultiplier = 1f + Mathf.Min(m_timeSinceRested / ConfigManager.ELossNoRestThreshold.Value, 1f) * (ConfigManager.ELossNoRestMultiplier.Value - 1f);
			}
		}

		public void UpdateMovementState()
		{
			lossEnergyMovementAdd = (pes.PlayerMoving ? (noRestMultiplier * seasonMultiplier * fitnessSkillMultiplier * lossEnergyRestedMult * ConfigManager.ELossMotionAdd.Value) : 0f);
		}

		public void UpdateEnergyValue()
		{
			float num = CalculateThresholdMultiplierForStat(ConfigManager.ELossLowEnergyThreshold.Value);
			float num2 = 1f - num * ConfigManager.ELossLowEnergyResist.Value;
			float num3 = num2 * (energyChange + lossEnergyMovementAdd);
			m_energyLoss = Mathf.Clamp(m_energyLoss + num3, 0f, m_maxEnergyLoss);
		}

		public void Recalculate()
		{
			Main.LogMessage("Recalculating Energy SE");
			m_maxEnergyLoss = baseMaxEnergyLoss + CalculateAdditionalMaxEnergy();
			lossEnergyRestedMult = CalculateRestedMultiplier();
			lossEnergyCarryWeightAdd = CalculateCarryWeightAdd();
			seasonMultiplier = CalculateSeasonMultiplier();
			staminaMeadMult = CalculateStaminaMeadMultiplier();
			fitnessSkillMultiplier = CalculateFitnessSkillMultiplier();
			energyChange = staminaMeadMult * seasonMultiplier * fitnessSkillMultiplier * CalculatePassiveLosses() - (CalculateGainsFromRest() + CalculateGainsFromStaminaMead());
		}

		public float CalculateRestedMultiplier()
		{
			return pes.PlayerRested ? ConfigManager.ELossRestedResist.Value : 1f;
		}

		public float CalculateCarryWeightAdd()
		{
			float value = ConfigManager.ELossHeavyLoadThreshold.Value;
			if (pes.PlayerCarryWeightPerc < value)
			{
				warningWeight = true;
				return 0f;
			}
			if (warningWeight)
			{
				SendPlayerMessage("$ea_energy_warningmessage_weight");
				warningWeight = false;
			}
			float num = CalculateThresholdMultiplierForStat(value);
			return num * ConfigManager.ELossHeavyLoadAdd.Value;
		}

		public float CalculatePassiveLosses()
		{
			float num = 0f;
			if (pes.PlayerCold)
			{
				num += ConfigManager.ELossColdAdd.Value;
			}
			if (pes.PlayerFreezing)
			{
				num += ConfigManager.ELossFreezingAdd.Value;
			}
			if (pes.PlayerWet)
			{
				num += ConfigManager.ELossWetAdd.Value;
			}
			if (pes.PlayerHungry)
			{
				num += ConfigManager.ELossHungryAdd.Value;
			}
			return lossEnergyRestedMult * num;
		}

		public float CalculateGainsFromRest()
		{
			float num = 0f;
			if (pes.PlayerSitting)
			{
				num += ConfigManager.ELossSittingRemove.Value;
			}
			if (pes.PlayerResting)
			{
				num += ConfigManager.ELossRestingRemove.Value;
			}
			if (pes.PlayerRested && !pes.PlayerResting && !pes.PlayerHasBadEnvironmentalStatus)
			{
				num += ConfigManager.ELossRestedRemove.Value;
			}
			if (pes.PlayerSitting && pes.PlayerResting)
			{
				num *= ConfigManager.ELossSittingRestingMultiplier.Value;
			}
			if (pes.PlayerSitting && pes.PlayerResting && pes.PlayerSheltered)
			{
				num *= ConfigManager.ELossSittingRestingShelterMultiplier.Value;
			}
			return m_maxEnergyLoss / baseMaxEnergyLoss * num;
		}

		public float CalculateGainsFromStaminaMead()
		{
			return pes.PlayerStaminaMead ? (ConfigManager.ELossStaminaMeadRemove.Value * m_maxEnergyLoss) : 0f;
		}

		public float CalculateAdditionalMaxEnergy()
		{
			float num = pes.FitnessSkillLevel / 100f;
			float num2 = ConfigManager.FitnessSkillMaxEnergyGain.Value - baseMaxEnergyLoss;
			return num * num2;
		}

		public float CalculateSeasonMultiplier()
		{
			if (pes.PlayerInSeasonExcludedBiome)
			{
				return seasonMultiplier = 1f;
			}
			return pes.EnvironmentSeasonState switch
			{
				EnvironmentSeason.Season.Spring => seasonMultiplier = ConfigManager.ESpringSeasonMultiplier.Value, 
				EnvironmentSeason.Season.Summer => seasonMultiplier = ConfigManager.ESummerSeasonMultiplier.Value, 
				EnvironmentSeason.Season.Fall => seasonMultiplier = ConfigManager.EFallSeasonMultiplier.Value, 
				EnvironmentSeason.Season.Winter => seasonMultiplier = ConfigManager.EWinterSeasonMultiplier.Value, 
				_ => seasonMultiplier = 1f, 
			};
		}

		public float CalculateStaminaMeadMultiplier()
		{
			return staminaMeadMult = (pes.PlayerStaminaMead ? (1f - ConfigManager.ELossStaminaMeadResist.Value) : 1f);
		}

		public float CalculateFitnessSkillMultiplier()
		{
			return 1f - pes.FitnessSkillFactor;
		}

		public void UpdateEffects()
		{
			UpdateRemoveRested();
			UpdateDamageMultOT();
			UpdateMoveSpeedMultOT();
			UpdateSkillGainMultOT();
			UpdateSkillLevelOT();
			UpdateStaminaRegenMultOT();
			UpdateStaminaRegenDelayOT();
		}

		public void UpdateRemoveRested()
		{
			if (!ConfigManager.ERestedLossEnabled.Value)
			{
				return;
			}
			float value = ConfigManager.ERestedLossThreshold.Value;
			if (!(m_energyLossPerc < value) && pes.PlayerRested && !pes.PlayerResting)
			{
				StatusEffect statusEffect = ((Character)player).m_seman.GetStatusEffect(SEMan.s_statusEffectRested);
				SE_Rested val = (SE_Rested)(object)((statusEffect is SE_Rested) ? statusEffect : null);
				if (!((Object)(object)val == (Object)null))
				{
					((Character)player).m_seman.RemoveStatusEffect((StatusEffect)(object)val, false);
				}
			}
		}

		public void UpdateDamageMultOT()
		{
			if (!ConfigManager.EDamageReductionEnabled.Value)
			{
				base.m_damageModifier = 1f;
				return;
			}
			float value = ConfigManager.EDamageReductionThreshold.Value;
			if (m_energyLossPerc < value)
			{
				warningDamage = true;
				base.m_damageModifier = 1f;
				return;
			}
			if (warningDamage)
			{
				SendPlayerMessage("$ea_energy_warningmessage_damage");
				warningDamage = false;
			}
			float num = CalculateThresholdMultiplierForStat(value);
			base.m_damageModifier = 1f - num * ConfigManager.EDamageMaxReduction.Value;
		}

		public void UpdateMoveSpeedMultOT()
		{
			if (!ConfigManager.EMoveSpeedReductionEnabled.Value)
			{
				base.m_speedModifier = 0f;
				return;
			}
			float value = ConfigManager.EMoveSpeedReductionMinThreshold.Value;
			if (m_energyLossPerc < value)
			{
				warningSpeed = true;
				base.m_speedModifier = 0f;
				return;
			}
			if (warningSpeed)
			{
				SendPlayerMessage("$ea_energy_warningmessage_movement");
				warningSpeed = false;
			}
			float num = CalculateThresholdMultiplierForStat(value);
			base.m_speedModifier = -1f * (num * ConfigManager.EMoveSpeedMaxReduction.Value);
		}

		public void UpdateSkillGainMultOT()
		{
			if (!ConfigManager.ESkillGainReductionEnabled.Value)
			{
				base.m_raiseSkillModifier = 0f;
				return;
			}
			float value = ConfigManager.ESkillGainReductionThreshold.Value;
			if (m_energyLossPerc < value)
			{
				warningSkillGain = true;
				base.m_raiseSkillModifier = 0f;
				return;
			}
			if (warningSkillGain)
			{
				SendPlayerMessage("$ea_energy_warningmessage_skillgain");
				warningSkillGain = false;
			}
			float num = CalculateThresholdMultiplierForStat(value);
			base.m_raiseSkillModifier = -1f * (num * ConfigManager.ESkillGainMaxReduction.Value);
		}

		public void UpdateSkillLevelOT()
		{
			if (!ConfigManager.ESkillLevelReductionEnabled.Value)
			{
				base.m_skillLevelModifier = 0f;
				return;
			}
			float value = ConfigManager.ESkillLevelReductionThreshold.Value;
			if (m_energyLossPerc < value)
			{
				warningSkillLevel = true;
				base.m_skillLevelModifier = 0f;
				return;
			}
			if (warningSkillLevel)
			{
				SendPlayerMessage("$ea_energy_warningmessage_skilllevel");
				warningSkillLevel = false;
			}
			float num = CalculateThresholdMultiplierForStat(value);
			base.m_skillLevelModifier = -1f * Mathf.Floor(num * ConfigManager.ESkillLevelMaxReduction.Value);
		}

		public void UpdateStaminaRegenMultOT()
		{
			if (!ConfigManager.EStaminaRegenEnabled.Value)
			{
				base.m_staminaRegenMultiplier = 1f;
				return;
			}
			float value = ConfigManager.EStaminaRegenMinThreshold.Value;
			if (m_energyLossPerc < value)
			{
				warningStaminaRegen = true;
				base.m_staminaRegenMultiplier = 1f;
				return;
			}
			if (warningStaminaRegen)
			{
				SendPlayerMessage("$ea_energy_warningmessage_staminaregen");
				warningStaminaRegen = false;
			}
			float num = CalculateThresholdMultiplierForStat(value);
			base.m_staminaRegenMultiplier = 1f - num * ConfigManager.EStaminaRegenMaxReduction.Value;
		}

		public void UpdateStaminaRegenDelayOT()
		{
			if (!ConfigManager.EStaminaRegenDelayEnabled.Value)
			{
				m_staminaRegenDelay = 0f;
				return;
			}
			float value = ConfigManager.EStaminaRegenDelayMinThreshold.Value;
			if (m_energyLossPerc < value)
			{
				warningStaminaDelay = true;
				m_staminaRegenDelay = 0f;
				return;
			}
			if (warningStaminaDelay)
			{
				SendPlayerMessage("$ea_energy_warningmessage_staminadelay");
				warningStaminaDelay = false;
			}
			float num = CalculateThresholdMultiplierForStat(value);
			m_staminaRegenDelay = num * ConfigManager.EStaminaRegenDelayMaxMultiplier.Value;
		}

		public float CalculateThresholdMultiplierForStat(float threshold)
		{
			return Mathf.Clamp((m_energyLoss - threshold) / (m_maxEnergyLoss - threshold), 0f, 1f);
		}

		public void ApplyEnergyGainFromFood(float stamina)
		{
			if (!pes.PlayerNoSkillDrain && !(countdownTimer > 0f))
			{
				float num = stamina * ConfigManager.ELossFoodStaminaRemove.Value;
				float num2 = m_maxEnergyLoss / baseMaxEnergyLoss;
				m_energyFromFood += num * num2;
			}
		}

		public void ApplyEnergyGainFromSleeping()
		{
			if (!pes.PlayerNoSkillDrain && !(countdownTimer > 0f))
			{
				float num = ConfigManager.ELossPercentageSleepRemove.Value / 100f * m_maxEnergyLoss;
				m_energyLoss -= num;
				if (m_energyLoss < 0f)
				{
					m_energyLoss = 0f;
				}
			}
		}

		public void ApplyEnergyLossFromStamina(float stamina)
		{
			if (!pes.PlayerNoSkillDrain && !(countdownTimer > 0f))
			{
				float num = stamina * (ConfigManager.ELossStaminaPointUsedAdd.Value + lossEnergyCarryWeightAdd);
				float num2 = lossEnergyRestedMult * seasonMultiplier * fitnessSkillMultiplier * noRestMultiplier * (1f - pes.FitnessSkillFactor) * num;
				m_energyLoss += num2;
				if (m_energyLoss > m_maxEnergyLoss)
				{
					num = m_energyLoss - m_maxEnergyLoss;
					m_energyLoss = m_maxEnergyLoss;
				}
				RaiseFitnessSkill(num);
				totalStaminaUseInCycle += stamina;
				totalEnergyUseInCycle += num2;
				lastRawLossInCycle = num;
			}
		}

		public void RaiseFitnessSkill(float amount)
		{
			((StatusEffect)this).m_character.RaiseSkill("Fitness", 0.2f * amount * ConfigManager.FitnessSkillGainFactor.Value);
		}

		public void LogStatistics()
		{
			Main.LogMessage("ENERGY SE UPDATE");
			Main.LogMessage("Energy: " + Mathf.Round(100f - m_energyLossPerc) + "( " + (m_maxEnergyLoss - m_energyLoss) + " / " + m_maxEnergyLoss + ")");
			Main.LogMessage("Rested Resist Mult: " + lossEnergyRestedMult);
			Main.LogMessage("No Rested Debuffs: +" + noRestMultiplier + "x (" + m_timeSinceRested + "s since last rested)");
			Main.LogMessage("Stamina Regen Multiplier: " + base.m_staminaRegenMultiplier + "x");
			Main.LogMessage("Stamina Regen Delay: +" + m_staminaRegenDelay + "s");
			Main.LogMessage("Seasonal Multiplier: " + seasonMultiplier + "x");
			Main.LogMessage("Fitness Skill Multiplier " + fitnessSkillMultiplier + "x");
			Main.LogMessage("Stamina Use in Cycle: " + totalStaminaUseInCycle);
			Main.LogMessage("Energy Loss from Stamina in Cycle: " + totalEnergyUseInCycle);
			Main.LogMessage("Last Raw Loss in Cycle: " + lastRawLossInCycle);
		}

		public void ResetCycleStats()
		{
			totalStaminaUseInCycle = 0f;
			totalEnergyUseInCycle = 0f;
			lastRawLossInCycle = 0f;
		}

		public void SendPlayerMessage(string text)
		{
			if (ConfigManager.DisplayEnergyWarningText.Value)
			{
				((StatusEffect)this).m_character.Message((MessageType)2, Localization.instance.Localize(text), 0, (Sprite)null);
			}
		}

		public bool CheckPlayerData()
		{
			if ((Object)(object)pes != (Object)null)
			{
				return true;
			}
			Main.LogMessage("Player environment stats is null.");
			Character character = ((StatusEffect)this).m_character;
			Player val = (Player)(object)((character is Player) ? character : null);
			if ((Object)(object)val == (Object)null)
			{
				Main.LogMessage("EnergySE not applied to a player.");
				return false;
			}
			player = val;
			pes = ((Character)player).m_seman.GetStatusEffect(SE_PlayerStats.Hash) as SE_PlayerStats;
			if ((Object)(object)pes == (Object)null)
			{
				return false;
			}
			return true;
		}

		public void UpdateIcon()
		{
			if (pes.PlayerNoSkillDrain)
			{
				((StatusEffect)this).m_icon = iconNoSkillDrain;
				return;
			}
			if (countdownTimer > 0f)
			{
				((StatusEffect)this).m_icon = iconNewSpawn;
				return;
			}
			int num = Mathf.CeilToInt((float)icons.Length * (m_energyLoss / m_maxEnergyLoss));
			if (num > icons.Length - 1)
			{
				num = icons.Length - 1;
			}
			((StatusEffect)this).m_icon = icons[num];
		}
	}
	[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(1)]
	[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(0)]
	public class SE_Hungry : SE_Stats
	{
		public static readonly int Hash = StringExtensionMethods.GetStableHashCode(Main.HungrySEName);

		public override void Setup(Character character)
		{
			((SE_Stats)this).Setup(character);
			((StatusEffect)this).m_name = "$ea_se_hungry";
			((StatusEffect)this).m_icon = Main.GetInstance().Bundle.LoadAsset<Sprite>("hungryicon");
		}

		public override void Stop()
		{
			((StatusEffect)this).Stop();
			((StatusEffect)this).m_ttl = 1f;
		}

		public override bool IsDone()
		{
			return false;
		}

		public override string GetTooltipString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("$ea_player_hungry_status");
			stringBuilder.Append(((SE_Stats)this).GetTooltipString());
			return stringBuilder.ToString();
		}
	}
	[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(0)]
	[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(1)]
	public class SE_PlayerStats : StatusEffect
	{
		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		public Player player;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		private SE_Vitality vitality;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		private SE_Energy energy;

		private List<string> playerState = new List<string>();

		private List<string> environmentState = new List<string>();

		private float player_base_health;

		private float player_base_stamina;

		private float player_base_stamina_regen_delay;

		private float player_carry_weight_perc;

		private bool player_no_skill_drain;

		private float player_body_armor;

		private bool player_healing_mead;

		private bool player_stamina_mead;

		private bool player_eitr_mead;

		private Biome player_in_biome = (Biome)895;

		private bool player_in_excluded_environment;

		private bool player_moving;

		private bool player_poison_resistant;

		private bool player_poison_very_resistant;

		private bool player_fire_resistant;

		private bool player_fire_very_resistant;

		private bool player_lightning_resistant;

		private bool player_lightning_very_resistant;

		private bool player_frost_resistant;

		private bool player_frost_very_resistant;

		private bool player_sheltered;

		private bool player_sitting;

		private bool player_near_fire;

		private bool player_resting;

		private bool player_rested;

		private bool player_wet;

		private bool player_cold;

		private bool player_freezing;

		private bool player_hungry;

		private bool player_poisoned;

		private bool player_burning;

		private bool player_shocked;

		private bool player_frozen;

		private bool environment_wet;

		private bool environment_cold;

		private bool environment_freezing;

		private EnvironmentSeason.Season environment_season_state;

		private float resistance_skill_level;

		private float resistance_skill_factor;

		private float fitness_skill_level;

		private float fitness_skill_factor;

		private bool recalculate = false;

		public float lastUpdateTime = 0f;

		public float lastLogTime = 0f;

		public static readonly int Hash = StringExtensionMethods.GetStableHashCode(Main.PlayerStatsSEName);

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(new byte[] { 2, 1, 1, 1 })]
		private Dictionary<string, Dictionary<string, float>> player_food_cache;

		public readonly string Health = "health";

		public readonly string Stamina = "stamina";

		public readonly string Eitr = "eitr";

		public readonly string Time = "time";

		public List<string> PlayerState => playerState;

		public List<string> EnvironmentState => environmentState;

		public float PlayerBaseHealth => player_base_health;

		public float PlayerBaseStamina => player_base_stamina;

		public float PlayerStaminaRegenDelay => player_base_stamina_regen_delay;

		public float PlayerCarryWeightPerc
		{
			get
			{
				return player_carry_weight_perc;
			}
			set
			{
				if (player_carry_weight_perc != value)
				{
					Main.LogMessage("Player carry weight changed to " + value + "%.");
					player_carry_weight_perc = value;
					recalculate = true;
				}
			}
		}

		public bool PlayerNoSkillDrain
		{
			get
			{
				return player_no_skill_drain;
			}
			set
			{
				if (player_no_skill_drain != value)
				{
					Main.LogMessage("Player no skill drain changed.");
					player_no_skill_drain = value;
					recalculate = true;
					playerState.CheckState(value, "No Skill Drain");
				}
			}
		}

		public float PlayerBodyArmor
		{
			get
			{
				return player_body_armor;
			}
			set
			{
				if (player_body_armor != value)
				{
					Main.LogMessage("Player armor changed.");
					player_body_armor = value;
					recalculate = true;
				}
			}
		}

		public bool PlayerHealingMead
		{
			get
			{
				return player_healing_mead;
			}
			set
			{
				if (player_healing_mead != value)
				{
					Main.LogMessage("Player healing mead changed.");
					player_healing_mead = value;
					recalculate = true;
					playerState.CheckState(value, "Using Healing Mead");
				}
			}
		}

		public bool PlayerStaminaMead
		{
			get
			{
				return player_stamina_mead;
			}
			set
			{
				if (player_stamina_mead != value)
				{
					Main.LogMessage("Player stamina mead changed.");
					player_stamina_mead = value;
					recalculate = true;
					playerState.CheckState(value, "Using Stamina Mead");
				}
			}
		}

		public bool PlayerEitrMead
		{
			get
			{
				return player_eitr_mead;
			}
			set
			{
				if (player_eitr_mead != value)
				{
					Main.LogMessage("Player eitr mead changed.");
					player_eitr_mead = value;
					recalculate = true;
					playerState.CheckState(value, "Using Eitr Mead");
				}
			}
		}

		public bool PlayerInSeasonExcludedBiome => (int)PlayerInBiome == 64 || (int)PlayerInBiome == 32 || (int)PlayerInBiome == 4;

		public Biome PlayerInBiome
		{
			get
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: 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)
				return player_in_biome;
			}
			set
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				if (player_in_biome != value)
				{
					Main.LogMessage("Change to biome");
					player_in_biome = value;
					recalculate = true;
				}
			}
		}

		public bool PlayerInHarshBiome => new List<Biome>
		{
			(Biome)32,
			(Biome)64
		}.Contains(PlayerInBiome);

		public bool PlayerInExcludedEnvironment
		{
			get
			{
				return player_in_excluded_environment;
			}
			set
			{
				if (player_in_excluded_environment != value)
				{
					Main.LogMessage("Change to excluded enviornment.");
					player_in_excluded_environment = value;
					recalculate = true;
					playerState.CheckState(value, "In Excluded Environment");
				}
			}
		}

		public bool PlayerMoving
		{
			get
			{
				return player_moving;
			}
			set
			{
				if (player_moving != value)
				{
					Main.LogMessage("Change to movement.");
					player_moving = value;
					playerState.CheckState(value, "Moving");
				}
			}
		}

		public bool PlayerPoisonResistant
		{
			get
			{
				return player_poison_resistant;
			}
			set
			{
				if (player_poison_resistant != value)
				{
					Main.LogMessage("Change to poison resistant.");
					player_poison_resistant = value;
					recalculate = true;
					playerState.CheckState(value, "Resistant vs Poison");
				}
			}
		}

		public bool PlayerPoisonVeryResistant
		{
			get
			{
				return player_poison_very_resistant;
			}
			set
			{
				if (player_poison_very_resistant != value)
				{
					Main.LogMessage("Change to poison very resistant.");
					player_poison_very_resistant = value;
					recalculate = true;
					playerState.CheckState(value, "Very Resistant vs Poison");
				}
			}
		}

		public bool PlayerFireResistant
		{
			get
			{
				return player_fire_resistant;
			}
			set
			{
				if (player_fire_resistant != value)
				{
					Main.LogMessage("Change to fire resistant.");
					player_fire_resistant = value;
					recalculate = true;
					playerState.CheckState(value, "Resistant vs Fire");
				}
			}
		}

		public bool PlayerFireVeryResistant
		{
			get
			{
				return player_fire_very_resistant;
			}
			set
			{
				if (player_fire_very_resistant != value)
				{
					Main.LogMessage("Change to fire very resistant.");
					player_fire_very_resistant = value;
					recalculate = true;
					playerState.CheckState(value, "Very Resistant vs Fire");
				}
			}
		}

		public bool PlayerLightningResistant
		{
			get
			{
				return player_lightning_resistant;
			}
			set
			{
				if (player_lightning_resistant != value)
				{
					Main.LogMessage("Change to lightning resistant.");
					player_lightning_resistant = value;
					recalculate = true;
					playerState.CheckState(value, "Resistant vs Lightning");
				}
			}
		}

		public bool PlayerLightningVeryResistant
		{
			get
			{
				return player_lightning_very_resistant;
			}
			set
			{
				if (player_lightning_very_resistant != value)
				{
					Main.LogMessage("Change to lightning very resistant.");
					player_lightning_very_resistant = value;
					recalculate = true;
					playerState.CheckState(value, "Very Resistant vs Lightning");
				}
			}
		}

		public EnvironmentSeason.Season EnvironmentSeasonState
		{
			get
			{
				return environment_season_state;
			}
			set
			{
				if (environment_season_state != value)
				{
					Main.LogMessage("Change to season.");
					environment_season_state = value;
					recalculate = true;
				}
			}
		}

		public bool PlayerFrostResistant
		{
			get
			{
				return player_frost_resistant;
			}
			set
			{
				if (player_frost_resistant != value)
				{
					Main.LogMessage("Change to frost resistant.");
					player_frost_resistant = value;
					recalculate = true;
					playerState.CheckState(value, "Resistant vs Frost");
				}
			}
		}

		public bool PlayerFrostVeryResistant
		{
			get
			{
				return player_frost_very_resistant;
			}
			set
			{
				if (player_frost_very_resistant != value)
				{
					Main.LogMessage("Change to frost very resistant.");
					player_frost_very_resistant = value;
					recalculate = true;
					playerState.CheckState(value, "Very Resistant vs Frost");
				}
			}
		}

		public bool PlayerSitting
		{
			get
			{
				return player_sitting;
			}
			set
			{
				if (player_sitting != value)
				{
					Main.LogMessage("Change to sitting.");
					player_sitting = value;
					recalculate = true;
					playerState.CheckState(value, "Sitting");
				}
			}
		}

		public bool PlayerSheltered
		{
			get
			{
				return player_sheltered;
			}
			set
			{
				if (player_sheltered != value)
				{
					Main.LogMessage("Change to sheltered.");
					player_sheltered = value;
					recalculate = true;
					playerState.CheckState(value, "In Shelter");
				}
			}
		}

		public bool PlayerNearFire
		{
			get
			{
				return player_near_fire;
			}
			set
			{
				if (player_near_fire != value)
				{
					Main.LogMessage("Change to near fire.");
					player_near_fire = value;
					recalculate = true;
					playerState.CheckState(value, "Near Fire");
				}
			}
		}

		public bool PlayerResting
		{
			get
			{
				return player_resting;
			}
			set
			{
				if (player_resting != value)
				{
					Main.LogMessage("Change to resting.");
					player_resting = value;
					recalculate = true;
					playerState.CheckState(value, "Resting");
				}
			}
		}

		public bool PlayerRested
		{
			get
			{
				return player_rested;
			}
			set
			{
				if (player_rested != value)
				{
					Main.LogMessage("Change to rested.");
					player_rested = value;
					recalculate = true;
					playerState.CheckState(value, "Rested");
				}
			}
		}

		public bool PlayerWet
		{
			get
			{
				return player_wet;
			}
			set
			{
				if (player_wet != value)
				{
					Main.LogMessage("Change to player wet.");
					player_wet = value;
					recalculate = true;
					playerState.CheckState(value, "Wet");
				}
			}
		}

		public bool PlayerCold
		{
			get
			{
				return player_cold;
			}
			set
			{
				if (player_cold != value)
				{
					Main.LogMessage("Change to player cold.");
					player_cold = value;
					recalculate = true;
					playerState.CheckState(value, "Cold");
				}
			}
		}

		public bool PlayerFreezing
		{
			get
			{
				return player_freezing;
			}
			set
			{
				if (player_freezing != value)
				{
					Main.LogMessage("Change to player freezing.");
					player_freezing = value;
					recalculate = true;
					playerState.CheckState(value, "Freezing");
				}
			}
		}

		public bool PlayerHungry
		{
			get
			{
				return player_hungry;
			}
			set
			{
				if (player_hungry != value)
				{
					Main.LogMessage("Change to player hungry.");
					player_hungry = value;
					recalculate = true;
					playerState.CheckState(value, "Hungry");
				}
			}
		}

		public bool PlayerPoisoned
		{
			get
			{
				return player_poisoned;
			}
			set
			{
				if (player_poisoned != value)
				{
					Main.LogMessage("Change to player poisoned.");
					player_poisoned = value;
					recalculate = true;
					playerState.CheckState(value, "Poisoned");
				}
			}
		}

		public bool PlayerBurning
		{
			get
			{
				return player_burning;
			}
			set
			{
				if (player_burning != value)
				{
					Main.LogMessage("Change to player burning.");
					player_burning = value;
					recalculate = true;
					playerState.CheckState(value, "Burning");
				}
			}
		}

		public bool PlayerShocked
		{
			get
			{
				return player_shocked;
			}
			set
			{
				if (player_shocked != value)
				{
					Main.LogMessage("Change to player shocked.");
					player_shocked = value;
					recalculate = true;
					playerState.CheckState(value, "Shocked");
				}
			}
		}

		public bool PlayerFrozen
		{
			get
			{
				return player_frozen;
			}
			set
			{
				if (player_frozen != value)
				{
					Main.LogMessage("Change to player frozen.");
					player_frozen = value;
					recalculate = true;
					playerState.CheckState(value, "Frozen");
				}
			}
		}

		public bool PlayerHasBadElementalStatus => PlayerPoisoned || PlayerBurning || PlayerShocked || PlayerFrozen;

		public bool PlayerHasBadEnvironmentalStatus => PlayerWet || PlayerCold || PlayerFreezing || PlayerInHarshBiome;

		public Dictionary<string, Dictionary<string, float>> PlayerFoodCache => player_food_cache;

		public bool EnvironmentWet
		{
			get
			{
				return environment_wet;
			}
			set
			{
				if (environment_wet != value)
				{
					Main.LogMessage("Change to environment wet.");
					environment_wet = value;
					recalculate = true;
					environmentState.CheckState(value, "Wet");
				}
			}
		}

		public bool EnvironmentCold
		{
			get
			{
				return environment_cold;
			}
			set
			{
				if (environment_cold != value)
				{
					Main.LogMessage("Change to environment cold.");
					environment_cold = value;
					recalculate = true;
					environmentState.CheckState(value, "Cold");
				}
			}
		}

		public bool EnvironmentFreezing
		{
			get
			{
				return environment_freezing;
			}
			set
			{
				if (environment_freezing != value)
				{
					Main.LogMessage("Change to enviornment freezing.");
					environment_freezing = value;
					recalculate = true;
					environmentState.CheckState(value, "Freezing");
				}
			}
		}

		public float ResistanceSkillLevel
		{
			get
			{
				return resistance_skill_level;
			}
			set
			{
				if (resistance_skill_level != value)
				{
					Main.LogMessage("Change to resistance skill level: " + value);
					resistance_skill_level = value;
					recalculate = true;
				}
			}
		}

		public float ResistanceSkillFactor
		{
			get
			{
				return resistance_skill_factor;
			}
			set
			{
				if (resistance_skill_factor != value)
				{
					Main.LogMessage("Change to resistance skill factor.");
					resistance_skill_factor = value;
				}
			}
		}

		public float FitnessSkillLevel
		{
			get
			{
				return fitness_skill_level;
			}
			set
			{
				if (fitness_skill_level != value)
				{
					Main.LogMessage("Change to fitness skill level: " + value);
					fitness_skill_level = value;
					recalculate = true;
				}
			}
		}

		public float FitnessSkillFactor
		{
			get
			{
				return fitness_skill_factor;
			}
			set
			{
				if (fitness_skill_factor != value)
				{
					Main.LogMessage("Change to fitness skill factor.");
					fitness_skill_factor = value;
				}
			}
		}

		public override void Setup(Character character)
		{
			((StatusEffect)this).Setup(character);
			base.m_name = "$ea_se_playerstats";
			if (!base.m_character.IsPlayer())
			{
				base.m_character.m_seman.RemoveStatusEffect((StatusEffect)(object)this, true);
			}
			ref Player reference = ref player;
			Character character2 = base.m_character;
			reference = (Player)(object)((character2 is Player) ? character2 : null);
			if ((Object)(object)player == (Object)null)
			{
				base.m_character.m_seman.RemoveStatusEffect((StatusEffect)(object)this, true);
			}
			CheckBaseStats();
			player_food_cache = new Dictionary<string, Dictionary<string, float>>();
		}

		public override bool IsDone()
		{
			return false;
		}

		public override void UpdateStatusEffect(float dt)
		{
			lastUpdateTime += dt;
			lastLogTime += dt;
			if (lastUpdateTime > 1f)
			{
				CheckPlayerAndEnvironmentalState();
				UpdateFoodCache();
				HandleVitality();
				HandleEnergy();
				AfterRecalculate();
				lastUpdateTime -= 1f;
			}
			if (lastLogTime > 10f)
			{
				LogStats();
				lastLogTime -= 10f;
			}
		}

		public void HandleVitality()
		{
			if (ConfigManager.VitalityEnabled.Value)
			{
				if (!((Character)player).m_seman.HaveStatusEffect(SE_Vitality.Hash))
				{
					((Character)player).m_seman.AddStatusEffect(SE_Vitality.Hash, false, 0, 0f);
					Main.LogMessage("Vitality status effect initialized");
				}
				vitality = ((Character)player).m_seman.GetStatusEffect(SE_Vitality.Hash) as SE_Vitality;
				if ((Object)(object)vitality != (Object)null && ShouldRecalculate())
				{
					vitality.Recalculate();
				}
			}
		}

		public void HandleEnergy()
		{
			if (ConfigManager.EnergyEnabled.Value)
			{
				if (!((Character)player).m_seman.HaveStatusEffect(SE_Energy.Hash))
				{
					((Character)player).m_seman.AddStatusEffect(SE_Energy.Hash, false, 0, 0f);
					Main.LogMessage("Energy status effect initialized");
				}
				SEMan seman = ((Character)player).m_seman;
				SE_Energy sE_Energy = ((seman != null) ? seman.GetStatusEffect(SE_Energy.Hash) : null) as SE_Energy;
				if ((Object)(object)sE_Energy != (Object)null && ShouldRecalculate())
				{
					sE_Energy.Recalculate();
				}
			}
		}

		public void CheckBaseStats()
		{
			player_base_health = player.m_baseHP;
			player_base_stamina = player.m_baseStamina;
			player_base_stamina_regen_delay = player.m_staminaRegenDelay;
		}

		public void CheckPlayerAndEnvironmentalState()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			DamageModifiers damageModifiers = ((Character)player).GetDamageModifiers((WeakSpot)null);
			DamageModifier modifier = ((DamageModifiers)(ref damageModifiers)).GetModifier((DamageType)256);
			DamageModifier modifier2 = ((DamageModifiers)(ref damageModifiers)).GetModifier((DamageType)32);
			DamageModifier modifier3 = ((DamageModifiers)(ref damageModifiers)).GetModifier((DamageType)128);
			DamageModifier modifier4 = ((DamageModifiers)(ref damageModifiers)).GetModifier((DamageType)64);
			PlayerInBiome = GetCurrentBiome();
			PlayerCarryWeightPerc = GetCarryWeightPerc();
			PlayerInExcludedEnvironment = CheckExcludedEnvironment();
			PlayerBodyArmor = ((Character)player).GetBodyArmor();
			PlayerHealingMead = HasStatusCategory("healthpotion");
			PlayerStaminaMead = HasStatusCategory("staminapotion");
			PlayerEitrMead = HasStatusCategory("eitrpotion");
			PlayerPoisonResistant = GetResistance(modifier) == 1;
			PlayerPoisonVeryResistant = GetResistance(modifier) == 2;
			PlayerFireResistant = GetResistance(modifier2) == 1;
			PlayerFireVeryResistant = GetResistance(modifier2) == 2;
			PlayerLightningResistant = GetResistance(modifier3) == 1;
			PlayerLightningVeryResistant = GetResistance(modifier3) == 2;
			PlayerFrostResistant = GetResistance(modifier4) == 1;
			PlayerFrostVeryResistant = GetResistance(modifier4) == 2;
			PlayerMoving = PlayerIsMoving();
			PlayerSitting = PlayerIsSitting();
			PlayerSheltered = PlayerIsSheltered();
			PlayerHungry = PlayerIsHungry();
			PlayerNoSkillDrain = HasStatusEffect(SEMan.s_statusEffectSoftDeath) && ConfigManager.DeathGrantsImmunity.Value;
			PlayerNearFire = HasStatusEffect(SEMan.s_statusEffectCampFire);
			PlayerResting = HasStatusEffect(SEMan.s_statusEffectResting);
			PlayerRested = HasStatusEffect(SEMan.s_statusEffectRested);
			PlayerCold = HasStatusEffect(SEMan.s_statusEffectCold);
			PlayerFreezing = HasStatusEffect(SEMan.s_statusEffectFreezing);
			PlayerWet = HasStatusEffect(SEMan.s_statusEffectWet);
			PlayerPoisoned = HasStatusEffect(SEMan.s_statusEffectPoison);
			PlayerBurning = HasStatusEffect(SEMan.s_statusEffectBurning);
			PlayerShocked = HasStatusEffect(SEMan.s_statusEffectLightning);
			PlayerFrozen = HasStatusEffect(SEMan.s_statusEffectFrost);
			EnvironmentWet = GetEnvironmentState("wet");
			EnvironmentCold = GetEnvironmentState("cold");
			EnvironmentFreezing = GetEnvironmentState("freezing");
			EnvironmentSeasonState = GetSeason();
			ResistanceSkillLevel = GetSkillLevel("Resistance");
			ResistanceSkillFactor = GetSkillEffectFactor("Resistance");
			FitnessSkillLevel = GetSkillLevel("Fitness");
			FitnessSkillFactor = GetSkillEffectFactor("Fitness");
		}

		private Biome GetCurrentBiome()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return Heightmap.FindBiome(((Component)player).gameObject.transform.position);
			}
			catch
			{
				return (Biome)895;
			}
		}

		private float GetCarryWeightPerc()
		{
			try
			{
				return Mathf.Floor(100f * Mathf.Clamp(((Humanoid)player).m_inventory.m_totalWeight / player.GetMaxCarryWeight(), 0f, 1f));
			}
			catch
			{
				return 0f;
			}
		}

		private bool CheckExcludedEnvironment()
		{
			try
			{
				return ConfigManager.VIgnoredEnvironments.Contains(EnvMan.instance.GetCurrentEnvironment().m_name);
			}
			catch
			{
				return false;
			}
		}

		private int GetResistance(DamageModifier modifier)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			if ((int)modifier != 1)
			{
				if ((int)modifier == 5)
				{
					return 2;
				}
				return 0;
			}
			return 1;
		}

		private bool HasStatusEffect(int status)
		{
			if (((Character)player).m_seman == null)
			{
				return false;
			}
			return ((Character)player).m_seman.HaveStatusEffect(status);
		}

		private bool HasStatusCategory(string category)
		{
			if (((Character)player).m_seman == null)
			{
				return false;
			}
			return ((Character)player).m_seman.HaveStatusEffectCategory(category);
		}

		private bool PlayerIsMoving()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Vector3 velocity = ((Character)player).m_body.velocity;
				return ((Vector3)(ref velocity)).magnitude > 0.01f;
			}
			catch
			{
				return false;
			}
		}

		private bool PlayerIsSitting()
		{
			try
			{
				return ((Character)player).IsSitting();
			}
			catch
			{
				return false;
			}
		}

		private bool PlayerIsSheltered()
		{
			try
			{
				return player.InShelter();
			}
			catch
			{
				return false;
			}
		}

		private bool PlayerIsHungry()
		{
			try
			{
				List<Food> foods = player.m_foods;
				return foods != null && foods.Count == 0;
			}
			catch
			{
				return false;
			}
		}

		private bool GetEnvironmentState(string state)
		{
			try
			{
				return state switch
				{
					"wet" => EnvMan.IsWet(), 
					"cold" => EnvMan.IsCold(), 
					"freezing" => EnvMan.IsFreezing(), 
					_ => false, 
				};
			}
			catch
			{
				return false;
			}
		}

		private EnvironmentSeason.Season GetSeason()
		{
			try
			{
				return EnvironmentSeason.GetSeason(ZoneSystem.instance);
			}
			catch
			{
				return EnvironmentSeason.Season.None;
			}
		}

		private float GetSkillLevel(string name)
		{
			try
			{
				return ((Character)(object)player).GetSkillLevel(name);
			}
			catch
			{
				return 0f;
			}
		}

		private float GetSkillEffectFactor(string name)
		{
			try
			{
				return ((Character)(object)player).GetSkillEffectFactor(name);
			}
			catch
			{
				return 0f;
			}
		}

		public void UpdateFoodCache()
		{
			bool flag = false;
			foreach (Food food2 in player.m_foods)
			{
				string name = food2.m_item.m_shared.m_name;
				float foodBurnTime = food2.m_item.m_shared.m_foodBurnTime;
				float food = food2.m_item.m_shared.m_food;
				float foodStamina = food2.m_item.m_shared.m_foodStamina;
				float foodEitr = food2.m_item.m_shared.m_foodEitr;
				if (!player_food_cache.ContainsKey(name))
				{
					Main.LogMessage("Food " + name + " not found in cache. Adding");
					Dictionary<string, float> dictionary = new Dictionary<string, float>();
					dictionary.Add(Health, food);
					dictionary.Add(Stamina, foodStamina);
					dictionary.Add(Eitr, foodEitr);
					dictionary.Add(Time, foodBurnTime);
					player_food_cache.Add(name, dictionary);
					flag = true;
				}
			}
			if (flag)
			{
				CleanupFoodEntries();
			}
		}

		public void CleanupFoodEntries()
		{
			Main.LogMessage("Food change - removing unused foods from list.");
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, Dictionary<string, float>> item in player_food_cache)
			{
				Main.LogMessage("Checking for " + item.Key + " in food list.");
				bool flag = false;
				foreach (Food food in player.m_foods)
				{
					if (item.Key == food.m_item.m_shared.m_name)
					{
						Main.LogMessage("Found.");
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					Main.LogMessage("Not found.");
					list.Add(item.Key);
				}
			}
			foreach (string item2 in list)
			{
				Main.LogMessage("Removing " + item2 + " from food cache for player.");
				player_food_cache.Remove(item2);
			}
			Main.LogMessage("Cache cleanup done.");
		}

		public bool ShouldRecalculate()
		{
			return recalculate;
		}

		public void AfterRecalculate()
		{
			recalculate = false;
		}

		public void LogStats()
		{
			Main.LogMessage("PLAYER STATUSES");
			Main.LogMessage("Environment Stats for Player " + player.GetPlayerID());
			Main.LogMessage("Player State: " + string.Join(", ", PlayerState.ToArray()));
			Main.LogMessage("Player Skill: Resistance: " + resistance_skill_level + " : " + resistance_skill_factor + ", Fitness: " + fitness_skill_level + " : " + fitness_skill_factor);
			Main.LogMessage("Environment State: " + string.Join(", ", EnvironmentState.ToArray()));
			Main.LogMessage("Season: " + EnvironmentSeasonState);
		}
	}
	[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(1)]
	[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(0)]
	public class SE_Vitality : SE_Stats
	{
		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(new byte[] { 2, 1 })]
		public Sprite[] icons;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		public Sprite iconNoSkillDrain;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		public Sprite iconNewSpawn;

		public float m_vulnerability = 0f;

		public float m_foodBurnMult = 1f;

		public float m_foodStatBurn = 1f;

		public float vulnerabilityChange = 0f;

		public float vulnerabilityFromDamage = 0f;

		public float vulnerabilitySkillResist = 0f;

		public float seasonMultiplier = 1f;

		public float armorReduction = 0f;

		public float updateTimerState = 0f;

		public float updateTimerStats = 0f;

		public float updateTimerIcon = 0f;

		public float updateTimerLogs = 0f;

		public float countdownTimer = 300f;

		public bool warningHealth = true;

		public bool warningStamina = true;

		public bool warningFood = true;

		public bool warningSpeed = true;

		public bool warningPhysical = true;

		public bool warningElemental = true;

		public bool physicalWeaknessActive = false;

		public bool elementalWeaknessActive = false;

		public readonly float vulnerabilityMin = 0f;

		public readonly float vulnerabilityMax = 100f;

		public readonly Dictionary<string, DamageModPair> weaknesses = new Dictionary<string, DamageModPair>
		{
			{
				"blunt",
				new DamageModPair
				{
					m_type = (DamageType)1,
					m_modifier = (DamageModifier)2
				}
			},
			{
				"slash",
				new DamageModPair
				{
					m_type = (DamageType)2,
					m_modifier = (DamageModifier)2
				}
			},
			{
				"pierce",
				new DamageModPair
				{
					m_type = (DamageType)4,
					m_modifier = (DamageModifier)2
				}
			},
			{
				"fire",
				new DamageModPair
				{
					m_type = (DamageType)32,
					m_modifier = (DamageModifier)2
				}
			},
			{
				"frost",
				new DamageModPair
				{
					m_type = (DamageType)64,
					m_modifier = (DamageModifier)2
				}
			},
			{
				"lightning",
				new DamageModPair
				{
					m_type = (DamageType)128,
					m_modifier = (DamageModifier)2
				}
			},
			{
				"poison",
				new DamageModPair
				{
					m_type = (DamageType)256,
					m_modifier = (DamageModifier)2
				}
			}
		};

		public readonly string[] statuses = new string[5] { "$ea_vulnerability_status_0", "$ea_vulnerability_status_1", "$ea_vulnerability_status_2", "$ea_vulnerability_status_3", "$ea_vulnerability_status_4" };

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		private Player player;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(2)]
		private SE_PlayerStats pes;

		public static readonly int Hash = StringExtensionMethods.GetStableHashCode(Main.VitalitySEName);

		public override void Setup(Character character)
		{
			((SE_Stats)this).Setup(character);
			((StatusEffect)this).m_name = "$ea_se_vitality";
			LoadIcons();
			((StatusEffect)this).m_icon = icons[0];
			m_vulnerability = 0f;
			base.m_tickInterval = 5f;
			updateTimerState = 0f;
			updateTimerStats = 0f;
			updateTimerIcon = 0f;
			updateTimerLogs = 0f;
			countdownTimer = ConfigManager.NewPlayerCooldown.Value;
			ref Player reference = ref player;
			Character character2 = ((StatusEffect)this).m_character;
			reference = (Player)(object)((character2 is Player) ? character2 : null);
			if ((Object)(object)player == (Object)null)
			{
				((StatusEffect)this).m_character.m_seman.RemoveStatusEffect((StatusEffect)(object)this, false);
				return;
			}
			if (player.IsMaterialKnown("$item_stone") || player.IsMaterialKnown("$item_wood"))
			{
				Main.LogMessage("Player knows a material. Cooldown disabled for Vitality status.");
				countdownTimer = 0f;
			}
			pes = ((Character)player).m_seman.GetStatusEffect(SE_PlayerStats.Hash) as SE_PlayerStats;
			if ((Object)(object)pes == (Object)null)
			{
				((StatusEffect)this).m_character.m_seman.RemoveStatusEffect((StatusEffect)(object)this, false);
			}
			else
			{
				Recalculate();
			}
		}

		public void LoadIcons()
		{
			Sprite[] array = (Sprite[])(object)new Sprite[10];
			for (int i = 0; i < 10; i++)
			{
				string text = "vitalityicon" + (i + 1);
				array[i] = Main.GetInstance().Bundle.LoadAsset<Sprite>(text);
			}
			icons = array;
			iconNoSkillDrain = Main.GetInstance().Bundle.LoadAsset<Sprite>("vitalityicondeath");
			iconNewSpawn = Main.GetInstance().Bundle.LoadAsset<Sprite>("vitalityiconnewplayer");
		}

		public override void Stop()
		{
			((StatusEffect)this).Stop();
			m_vulnerability = 0f;
			base.m_healthPerTick = 0f;
			base.m_healthRegenMultiplier = 1f;
			base.m_staminaRegenMultiplier = 1f;
			m_foodBurnMult = 1f;
			base.m_mods = new List<DamageModPair>();
			((StatusEffect)this).m_ttl = 1f;
			updateTimerState = 0f;
			updateTimerStats = 0f;
			updateTimerIcon = 0f;
			updateTimerLogs = 0f;
			countdownTimer = ConfigManager.NewPlayerCooldown.Value;
		}

		public override bool IsDone()
		{
			return false;
		}

		public override string GetIconText()
		{
			if (pes.PlayerNoSkillDrain)
			{
				return "";
			}
			if (countdownTimer > 0f)
			{
				return StatusEffect.GetTimeString(countdownTimer, false, false);
			}
			if (!ConfigManager.DisplayVitalityPercentage.Value)
			{
				return "";
			}
			int num = 100 - Mathf.FloorToInt(m_vulnerability);
			return $"{num}%";
		}

		public override string GetTooltipString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (pes.PlayerNoSkillDrain)
			{
				stringBuilder.Append("$ea_player_vulnerability_immune \n");
				return stringBuilder.ToString();
			}
			if (countdownTimer > 0f)
			{
				stringBuilder.AppendFormat("$ea_player_vulnerability_cooldown: {0}s. \n", Mathf.Ceil(countdownTimer));
				return stringBuilder.ToString();
			}
			stringBuilder.Append(GetVulnerabilityStatus());
			if (pes.PlayerHealingMead)
			{
				stringBuilder.Append("$ea_player_healing_mead \n");
			}
			if (vulnerabilityChange > 0f)
			{
				if (!pes.PlayerSheltered && (pes.EnvironmentCold || pes.EnvironmentFreezing))
				{
					stringBuilder.Append("$ea_player_coldfreezing_vitality \n");
				}
				if (pes.PlayerHungry)
				{
					stringBuilder.Append("$ea_player_hungry_vitality \n");
				}
				if (pes.PlayerInHarshBiome)
				{
					stringBuilder.Append("$ea_player_harshbiome_vitality \n");
				}
				if (pes.PlayerSheltered && !pes.PlayerNearFire && pes.EnvironmentFreezing)
				{
					stringBuilder.Append("$ea_player_too_cold_shelter_vitality \n");
				}
			}
			else if (vulnerabilityChange < 0f && m_vulnerability > 0.1f)
			{
				stringBuilder.Append("$ea_player_recovering_vitality \n");
			}
			stringBuilder.Append(((SE_Stats)this).GetTooltipString());
			if (base.m_healthPerTick != 0f)
			{
				stringBuilder.AppendFormat("$se_health: <color=orange>{0}</color> \n", Mathf.Floor(base.m_healthPerTick).ToString("+0;-0"));
			}
			if (m_foodBurnMult >= 1.01f)
			{
				stringBuilder.AppendFormat("$ea_se_foodburn: <color=orange>{0}</color> \n", (Mathf.Round(m_foodBurnMult * 100f) / 100f).ToString());
			}
			return stringBuilder.ToString();
		}

		public string GetVulnerabilityStatus()
		{
			int num = Mathf.Clamp(Mathf.FloorToInt(m_vulnerability / (100f / (float)statuses.Length)), 0, statuses.Length - 1);
			return statuses[num] + "\n";
		}

		public override void UpdateStatusEffect(float dt)
		{
			if ((Object)(object)pes == (Object)null)
			{
				((StatusEffect)this).m_character.m_seman.RemoveStatusEffect((StatusEffect)(object)this, false);
			}
			((SE_Stats)this).UpdateStatusEffect(dt);
			((StatusEffect)this).m_ttl = 1f;
			if (countdownTimer <= 0f && !pes.PlayerNoSkillDrain)
			{
				updateTimerState += dt;
				updateTimerStats += dt;
			}
			updateTimerIcon += dt;
			updateTimerLogs += dt;
			if (!((Object)(object)player == (Object)null))
			{
				if (updateTimerState >= 1f && countdownTimer <= 0f && !pes.PlayerNoSkillDrain)
				{
					UpdateVulnerabilityValue();
					RaiseResistanceSkill();
					updateTimerState -= 1f;
				}
				if (updateTimerStats >= 5f && countdownTimer <= 0f && !pes.PlayerNoSkillDrain)
				{
					UpdateEffects();
					UpdateTutorial();
					updateTimerStats -= 5f;
				}
				if (updateTimerLogs >= 10f)
				{
					LogStatistics();
					updateTimerLogs -= 10f;
				}
				if (countdownTimer > 0f)
				{
					countdownTimer -= dt;
				}
				else
				{
					countdownTimer = 0f;
				}
				if (updateTimerIcon > 1f)
				{
					UpdateIcon();
					updateTimerIcon -= 1f;
				}
			}
		}

		public void UpdateTutorial()
		{
			if (m_vulnerability > 10f)
			{
				player.ShowTutorial("EnvironmentalAwarenessVitality", false);
			}
			if (m_vulnerability > 60f)
			{
				player.ShowTutorial("EnvironmentalAwarenessVitalityLow", false);
			}
		}

		public void Recalculate()
		{
			Main.LogMessage("Recalculating Vitality Change");
			vulnerabilitySkillResist = CalculateResistanceFromSkill();
			seasonMultiplier = CalculateSeasonMultiplier();
			vulnerabilityChange = CalculateVulnerabilityChange();
		}

		public void UpdateVulnerabilityValue()
		{
			m_vulnerability = Mathf.Clamp(m_vulnerability + vulnerabilityChange + vulnerabilityFromDamage, vulnerabilityMin, vulnerabilityMax);
			vulnerabilityFromDamage = 0f;
		}

		public float CalculateVulnerabilityChange()
		{
			float num = CalculateArmorReduction() * CalculateLossFromEnvironment() + CalculateHungerLoss();
			float num2 = CalculateRecoveryFromWarmShelteredRestingPassive() + CalculateRecoveryFromHealthMead();
			return vulnerabilitySkillResist * num - num2;
		}

		public float CalculateLossFromEnvironment()
		{
			float result = 0f;
			if (pes.PlayerInExcludedEnvironment)
			{
				return result;
			}
			float num = 0f;
			float num2 = 0f;
			float num3 = 0f;
			if (pes.EnvironmentCold && !pes.EnvironmentFreezing && !pes.PlayerNearFire)
			{
				num = ConfigManager.VColdAdd.Value;
			}
			if (pes.EnvironmentFreezing && (!pes.PlayerNearFire || !pes.PlayerSheltered))
			{
				num2 = ConfigManager.VFreezingAdd.Value;
			}
			if (pes.PlayerWet)
			{
				num3 = ConfigManager.VWetAdd.Value;
			}
			result = num + num2 + num3;
			if (num > 0f && num3 > 0f)
			{
				result *= ConfigManager.VColdWetMultiplier.Value;
			}
			if (num2 > 0f && num3 > 0f)
			{
				result *= ConfigManager.VFreezingWetMultiplier.Value;
			}
			if (pes.PlayerFrostResistant && pes.PlayerFrostVeryResistant)
			{
				result *= ConfigManager.VFrostResistantMultiplier.Value;
			}
			if (pes.PlayerFrostVeryResistant)
			{
				result *= ConfigManager.VFrostVeryResistantMultiplier.Value;
			}
			float num4 = 0f;
			num4 += CalculateStatusEffectLoss(pes.PlayerPoisoned, pes.PlayerPoisonVeryResistant, ConfigManager.VPoisonVeryResistantMultiplier.Value, pes.PlayerPoisonResistant, ConfigManager.VPoisonResistantMultiplier.Value, ConfigManager.VPoisonDamageAdd.Value);
			num4 += CalculateStatusEffectLoss(pes.PlayerBurning, pes.PlayerFireVeryResistant, ConfigManager.VFireVeryResistantMultiplier.Value, pes.PlayerFireResistant, ConfigManager.VFireResistantMultiplier.Value, ConfigManager.VBurningDamageAdd.Value);
			num4 += CalculateStatusEffectLoss(pes.PlayerShocked, pes.PlayerLightningVeryResistant, ConfigManager.VLightningVeryResistantMultiplier.Value, pes.PlayerLightningResistant, ConfigManager.VLightningResistantMultiplier.Value, ConfigManager.VShockDamageAdd.Value);
			num4 += CalculateStatusEffectLoss(pes.PlayerFrozen, pes.PlayerFrostVeryResistant, ConfigManager.VFrostVeryResistantMultiplier.Value, pes.PlayerFrostResistant, ConfigManager.VFrostResistantMultiplier.Value, ConfigManager.VFrostDamageAdd.Value);
			return seasonMultiplier * (result + CalculateBiomePassiveLoss()) + num4;
		}

		public float CalculateStatusEffectLoss(bool debuffType, bool vresistant, float vresistantmult, bool resistant, float resistantmult, float damage)
		{
			float result = 0f;
			if (debuffType && damage > 0f)
			{
				float num = 1f;
				if (vresistant)
				{
					num = vresistantmult;
				}
				else if (resistant)
				{
					num = resistantmult;
				}
				result = num * damage;
			}
			return result;
		}

		public float CalculateHungerLoss()
		{
			return pes.PlayerHungry ? ConfigManager.VHungerAdd.Value : 0f;
		}

		public float CalculateBiomePassiveLoss()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			float num = 1f;
			Biome playerInBiome = pes.PlayerInBiome;
			Biome val = playerInBiome;
			if ((int)val != 32)
			{
				if ((int)val == 64)
				{
					if (pes.PlayerFrostVeryResistant)
					{
						num = ConfigManager.VFrostVeryResistantMultiplier.Value;
					}
					else if (pes.PlayerFrostResistant)
					{
						num = ConfigManager.VFrostResistantMultiplier.Value;
					}
					return num * ConfigManager.VDeepNorthPassiveAdd.Value;
				}
				return 0f;
			}
			if (pes.PlayerFireVeryResistant)
			{
				num = ConfigManager.VFireVeryResistantMultiplier.Value;
			}
			else if (pes.PlayerFireResistant)
			{
				num = ConfigManager.VFireResistantMultiplier.Value;
			}
			return num * ConfigManager.VAshlandsPassiveAdd.Value;
		}

		public float CalculateSeasonMultiplier()
		{
			if (pes.PlayerInSeasonExcludedBiome)
			{
				return seasonMultiplier = 1f;
			}
			return pes.EnvironmentSeasonState switch
			{
				EnvironmentSeason.Season.Spring => seasonMultiplier = ConfigManager.VSpringSeasonalMultiplier.Value, 
				EnvironmentSeason.Season.Summer => seasonMultiplier = ConfigManager.VSummerSeasonalMultiplier.Value, 
				EnvironmentSeason.Season.Fall => seasonMultiplier = ConfigManager.VFallSeasonalMultiplier.Value, 
				EnvironmentSeason.Season.Winter => seasonMultiplier = ConfigManager.VWinterSeasonalMultiplier.Value, 
				_ => seasonMultiplier = 1f, 
			};
		}

		public float CalculateResistanceFromSkill()
		{
			return vulnerabilitySkillResist = 1f - pes.ResistanceSkillFactor;
		}

		public float CalculateRecoveryFromWarmShelteredRestingPassive()
		{
			float num = 0f;
			float num2 = 0f;
			if (pes.PlayerSheltered)
			{
				num = ConfigManager.VShelteredRemove.Value;
				if (pes.PlayerWet)
				{
					num *= 0.1f;
				}
			}
			if (pes.EnvironmentCold || pes.EnvironmentFreezing)
			{
				if (pes.PlayerNearFire && !pes.PlayerWet && !pes.PlayerHasBadElementalStatus && pes.PlayerSheltered)
				{
					num2 = ConfigManager.VHeatRemove.Value;
				}
			}
			else if (pes.PlayerNearFire && !pes.PlayerWet && !pes.PlayerHasBadElementalStatus)
			{
				num2 = ConfigManager.VHeatRemove.Value;
			}
			float num3 = num + num2;
			if (num2 > 0f && num > 0f)
			{
				num3 *= ConfigManager.VHeatShelteredMultiplier.Value;
			}
			if (pes.PlayerResting)
			{
				num3 += ConfigManager.VRestingRemove.Value;
			}
			if (pes.PlayerRested)
			{
				num3 += ConfigManager.VRestedRemove.Value;
			}
			if (!pes.PlayerHungry && !pes.PlayerHasBadEnvironmentalStatus && !pes.PlayerHasBadElementalStatus)
			{
				num3 += ConfigManager.VPassiveRemove.Value;
			}
			float num4 = 1f;
			if (pes.PlayerHungry)
			{
				num4 = 0.1f;
			}
			return num4 * num3;
		}

		public float CalculateRecoveryFromHealthMead()
		{
			return pes.PlayerHealingMead ? ConfigManager.VHealthPotionRemove.Value : 0f;
		}

		public float CalculateArmorReduction()
		{
			float num = Mathf.Max(pes.PlayerBodyArmor - (float)ConfigManager.VResistanceMinArmorThreshold.Value, 0f);
			return armorReduction = Mathf.Pow(ConfigManager.VResistancePerArmorPoint.Value, num);
		}

		public void UpdateIcon()
		{
			if (pes.PlayerNoSkillDrain)
			{
				((StatusEffect)this).m_icon = iconNoSkillDrain;
				return;
			}
			if (countdownTimer > 0f)
			{
				((StatusEffect)this).m_icon = iconNewSpawn;
				return;
			}
			int num = Mathf.CeilToInt((float)icons.Length * (m_vulnerability / 100f));
			if (num > icons.Length - 1)
			{
				num = icons.Length - 1;
			}
			((StatusEffect)this).m_icon = icons[num];
		}

		public void UpdateEffects()
		{
			UpdateHealthDoT();
			UpdateStaminaUseMultOT();
			UpdateMoveSpeedMultOT();
			UpdateFoodBurnMultOT();
			UpdatePhysicalWeakness();
			UpdateElementalWeakness();
			UpdateFoodStats();
		}

		public void UpdateHealthDoT()
		{
			if (!ConfigManager.VHealthDamageEnabled.Value)
			{
				base.m_healthPerTick = 0f;
				base.m_healthRegenMultiplier = 1f;
				return;
			}
			float value = ConfigManager.VHealthDamageMinStartThreshold.Value;
			if (m_vulnerability < value)
			{
				warningHealth = true;
				base.m_healthPerTick = 0f;
				base.m_healthRegenMultiplier = 1f;
				return;
			}
			if (warningHealth)
			{
				SendPlayerMessage("$ea_vitality_warningmessage_health");
				warningHealth = false;
			}
			float num = CalculateThresholdMultiplierForStat(value);
			base.m_healthPerTick = -1f * num * ConfigManager.VHealthMaxDamageOverTime.Value;
			base.m_healthRegenMultiplier = 1f - num * ConfigManager.VHealthMaxRegenReduction.Value;
		}

		public void UpdateStaminaUseMultOT()
		{
			if (!ConfigManager.VStaminaRegenReductionEnabled.Value)
			{
				base.m_staminaRegenMultiplier = 1f;
				return;
			}
			float value = ConfigManager.VStaminaRegenReductionThreshold.Value;
			if (m_vulnerability < value)
			{
				warningStamina = true;
				base.m_staminaRegenMultiplier = 1f;
				return;
			}
			if (warningStamina)
			{
				SendPlayerMessage("$ea_vitality_warningmessage_stamina");
				warningStamina = false;
			}
			float num = CalculateThresholdMultiplierForStat(value);
			base.m_staminaRegenMultiplier = 1f - num * ConfigManager.VStaminaRegenMaxReduction.Value;
		}

		public void UpdateMoveSpeedMultOT()
		{
			if (!ConfigManager.VMoveSpeedReductionEnabled.Value)
			{
				base.m_speedModifier = 0f;
				return;
			}
			float value = ConfigManager.VMoveSpeedMinStartThreshold.Value;
			if (m_vulnerability < value)
			{
				warningSpeed = true;
				base.m_speedModifier = 0f;
				return;
			}
			if (warningSpeed)
			{
				SendPlayerMessage("$ea_vitality_warningmessage_movement");
				warningSpeed = false;
			}
			float num = CalculateThresholdMultiplierForStat(value);
			base.m_speedModifier = -1f * (num * ConfigManager.VMoveSpeedMaxReduction.Value);
		}

		public void UpdateFoodBurnMultOT()
		{
			if (!ConfigManager.VFoodBurnRateEnabled.Value)
			{
				m_foodBurnMult = 1f;
				m_foodStatBurn = 1f;
				return;
			}
			float value = ConfigManager.VFoodBurnMinStartThreshold.Value;
			if (m_vulnerability < value)
			{
				warningFood = true;
				m_foodBurnMult = 1f;
				m_foodStatBurn = 1f;
				return;
			}
			if (warningFood)
			{
				SendPlayerMessage("$ea_vitality_warningmessage_foodburn");
				warningFood = false;
			}
			float num = CalculateThresholdMultiplierForStat(value);
			m_foodBurnMult = 1f + num * (ConfigManager.VFoodBurnMaxOverTime.Value - 1f);
			m_foodStatBurn = Mathf.Sqrt(m_foodBurnMult);
		}

		public void UpdatePhysicalWeakness()
		{
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Invalid comparison between Unknown and I4
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Invalid comparison between Unknown and I4
			if (!ConfigManager.VPhysicalWeaknessEnabled.Value)
			{
				return;
			}
			if (m_vulnerability < ConfigManager.VPhysicalWeaknessThreshold.Value)
			{
				warningPhysical = true;
				if (!physicalWeaknessActive)
				{
					return;
				}
				for (int num = base.m_mods.Count - 1; num >= 0; num--)
				{
					DamageModPair val = base.m_mods[num];
					DamageType type = val.m_type;
					DamageType val2 = type;
					if (val2 - 1 <= 1 || (int)val2 == 4)
					{
						base.m_mods.RemoveAt(num);
					}
				}
				physicalWeaknessActive = false;
			}
			else
			{
				if (warningPhysical)
				{
					SendPlayerMessage("$ea_vitality_warningmessage_physical");
					warningPhysical = false;
				}
				if (!physicalWeaknessActive)
				{
					base.m_mods.Add(weaknesses["blunt"]);
					base.m_mods.Add(weaknesses["slash"]);
					base.m_mods.Add(weaknesses["pierce"]);
					physicalWeaknessActive = true;
				}
			}
		}

		public void UpdateElementalWeakness()
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Invalid comparison between Unknown and I4
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Invalid comparison between Unknown and I4
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Invalid comparison between Unknown and I4
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Invalid comparison between Unknown and I4
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			if (!ConfigManager.VElementalWeaknessEnabled.Value)
			{
				return;
			}
			if (m_vulnerability < ConfigManager.VElementalWeaknessThreshold.Value)
			{
				warningElemental = true;
				if (!elementalWeaknessActive)
				{
					return;
				}
				for (int num = base.m_mods.Count - 1; num >= 0; num--)
				{
					DamageModPair val = base.m_mods[num];
					DamageType type = val.m_type;
					DamageType val2 = type;
					if ((int)val2 <= 64)
					{
						if ((int)val2 != 32 && (int)val2 != 64)
						{
							continue;
						}
					}
					else if ((int)val2 != 128 && (int)val2 != 256)
					{
						continue;
					}
					base.m_mods.RemoveAt(num);
				}
				elementalWeaknessActive = false;
			}
			else
			{
				if (warningElemental)
				{
					SendPlayerMessage("$ea_vitality_warningmessage_elemental");
					warningElemental = false;
				}
				if (!elementalWeaknessActive)
				{
					base.m_mods.Add(weaknesses["fire"]);
					base.m_mods.Add(weaknesses["frost"]);
					base.m_mods.Add(weaknesses["lightning"]);
					base.m_mods.Add(weaknesses["poison"]);
					elementalWeaknessActive = true;
				}
			}
		}

		public void UpdateFoodStats()
		{
			Dictionary<string, Dictionary<string, float>> playerFoodCache = pes.PlayerFoodCache;
			foreach (Food food in player.m_foods)
			{
				string name = food.m_item.m_shared.m_name;
				if (!playerFoodCache.TryGetValue(name, out var value))
				{
					Main.LogMessage("Could not find food with name " + name + " in cache. Skipping.");
					continue;
				}
				food.m_item.m_shared.m_foodBurnTime = value[PlayerFoodCache.Time] / m_foodBurnMult;
				if (food.m_time > food.m_item.m_shared.m_foodBurnTime)
				{
					food.m_time = food.m_item.m_shared.m_foodBurnTime;
				}
				Main.LogMessage("Food burn time for " + food.m_item.m_shared.m_name + ": " + value[PlayerFoodCache.Time] + " -> " + food.m_item.m_shared.m_foodBurnTime);
				if (ConfigManager.VFoodBurnStatReduction.Value)
				{
					food.m_health = value[PlayerFoodCache.Health] / m_foodStatBurn;
					food.m_stamina = value[PlayerFoodCache.Stamina] / m_foodStatBurn;
					food.m_eitr = value[PlayerFoodCache.Eitr] / m_foodStatBurn;
					Main.LogMessage("Food stats: HP: " + value[PlayerFoodCache.Health] + " -> " + Mathf.Round(food.m_health) + ", Stamina: " + value[PlayerFoodCache.Stamina] + " -> " + Mathf.Round(food.m_stamina) + ", Eitr: " + value[PlayerFoodCache.Eitr] + " -> " + Mathf.Round(food.m_eitr));
				}
			}
		}

		public float CalculateThresholdMultiplierForStat(float threshold)
		{
			return Mathf.Clamp((m_vulnerability - threshold) / (vulnerabilityMax - threshold), 0f, 1f);
		}

		public void RaiseResistanceSkill()
		{
			if (!((Object)(object)player == (Object)null))
			{
				float value = ConfigManager.ResistanceSkillGainMinThreshold.Value;
				if (!(m_vulnerability <= value))
				{
					float num = CalculateThresholdMultiplierForStat(value);
					((Character)(object)player).RaiseSkill("Resistance", num * ConfigManager.ResistanceSkillGainFactor.Value);
				}
			}
		}

		public void SendPlayerMessage(string text)
		{
			if (ConfigManager.DisplayVitalityWarningTexts.Value)
			{
				((StatusEffect)this).m_character.Message((MessageType)2, Localization.instance.Localize(text), 0, (Sprite)null);
			}
		}

		public void LogStatistics()
		{
			Main.LogMessage("VITALITY SE UPDATE");
			if (countdownTimer > 0f)
			{
				Main.LogMessage("Countdown: " + Mathf.Floor(countdownTimer) + "s");
				return;
			}
			Main.LogMessage("Vitality: " + Mathf.Round(100f * (100f - m_vulnerability)) / 100f + "%");
			Main.LogMessage("HP: " + Mathf.Round(100f * base.m_healthPerTick) / 100f + "HP/t");
			Main.LogMessage("Stamina Regen Multiplier: " + Mathf.Round(100f * base.m_staminaRegenMultiplier) / 100f + "x");
			Main.LogMessage("Move Speed:" + Mathf.Round(100f * base.m_speedModifier) / 100f);
			Main.LogMessage("Food Burn Multiplier: " + Mathf.Round(100f * m_foodBurnMult) / 100f + "x");
			Main.LogMessage("Food Stat Multiplier: " + Mathf.Round(100f * m_foodStatBurn) / 100f + "x");
		}

		public void ApplyVulnerabilityFromDamage(float damage)
		{
			if (!pes.PlayerNoSkillDrain && !(countdownTimer > 0f))
			{
				vulnerabilityFromDamage += vulnerabilitySkillResist * armorReduction * ConfigManager.VHPDamageAdd.Value * damage;
			}
		}
	}
}
namespace EnvironmentalAwareness.Patch
{
	internal class ObjectDB_Awake
	{
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		public static class ObjectDB_Awake_Patches
		{
			[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(1)]
			[HarmonyPriority(700)]
			public static void Postfix(ObjectDB __instance)
			{
				SE_PlayerStats playerStats = Main.GetInstance().PlayerStats;
				if (!__instance.m_StatusEffects.Contains((StatusEffect)(object)playerStats))
				{
					Main.LogMessage("Adding PlayerStats invisible status effect to ObjectDB.");
					__instance.m_StatusEffects.Add((StatusEffect)(object)playerStats);
				}
				SE_Vitality vitality = Main.GetInstance().Vitality;
				if (!__instance.m_StatusEffects.Contains((StatusEffect)(object)vitality))
				{
					Main.LogMessage("Adding Vitality status effect to ObjectDB.");
					__instance.m_StatusEffects.Add((StatusEffect)(object)vitality);
				}
				SE_Energy energy = Main.GetInstance().Energy;
				if (!__instance.m_StatusEffects.Contains((StatusEffect)(object)energy))
				{
					Main.LogMessage("Adding Energy status effect to ObjectDB.");
					__instance.m_StatusEffects.Add((StatusEffect)(object)energy);
				}
				SE_Hungry hungry = Main.GetInstance().Hungry;
				if (!__instance.m_StatusEffects.Contains((StatusEffect)(object)hungry))
				{
					Main.LogMessage("Adding Hungry status effect to ObjectDB.");
					__instance.m_StatusEffects.Add((StatusEffect)(object)hungry);
				}
			}
		}
	}
	internal class Player_EatFood
	{
		[HarmonyPatch(typeof(Player), "EatFood")]
		public static class Player_EatFood_Patches
		{
			[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(1)]
			[HarmonyPriority(700)]
			public static void Postfix(Player __instance, ItemData item, bool __result)
			{
				if (__result && ConfigManager.EnergyEnabled.Value && ((Character)__instance).m_seman.HaveStatusEffect(SE_Energy.Hash))
				{
					SE_Energy sE_Energy = ((Character)__instance).m_seman.GetStatusEffect(SE_Energy.Hash) as SE_Energy;
					if (!((Object)(object)sE_Energy == (Object)null) && item.m_shared.m_foodStamina != 0f)
					{
						sE_Energy.ApplyEnergyGainFromFood(item.m_shared.m_foodStamina);
					}
				}
			}
		}
	}
	internal class Player_OnDamaged
	{
		[HarmonyPatch(typeof(Player), "OnDamaged")]
		public static class Player_OnDamaged_Patches
		{
			[HarmonyPriority(700)]
			[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(1)]
			public static void Postfix(Player __instance, HitData hit)
			{
				if (!ConfigManager.VitalityEnabled.Value || ((Character)__instance).m_seman.HaveStatusEffect(SE_Vitality.Hash))
				{
					return;
				}
				SE_Vitality sE_Vitality = ((Character)__instance).m_seman.GetStatusEffect(SE_Vitality.Hash) as SE_Vitality;
				if (!((Object)(object)sE_Vitality == (Object)null))
				{
					float totalDamage = hit.GetTotalDamage();
					if (!(totalDamage < 1f))
					{
						sE_Vitality.ApplyVulnerabilityFromDamage(totalDamage);
					}
				}
			}
		}
	}
	internal class Player_OnSpawned
	{
		[HarmonyPatch(typeof(Player), "OnSpawned")]
		public static class Player_OnSpawned_Patches
		{
			[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(1)]
			[HarmonyPriority(700)]
			public static void Postfix(Player __instance)
			{
				Main.LogMessage("Player with ID " + __instance.GetPlayerID() + " spawned.");
			}
		}
	}
	internal class Player_RPC_UseStamina
	{
		[HarmonyPatch(typeof(Player), "RPC_UseStamina")]
		public static class Player_RPC_UseStamina_Patches
		{
			[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(1)]
			[HarmonyPriority(700)]
			public static void Postfix(Player __instance, float v)
			{
				if (ConfigManager.EnergyEnabled.Value && !((Character)__instance).InIntro() && ((Character)__instance).m_seman.HaveStatusEffect(SE_Energy.Hash))
				{
					SE_Energy sE_Energy = ((Character)__instance).m_seman.GetStatusEffect(SE_Energy.Hash) as SE_Energy;
					if (!((Object)(object)sE_Energy == (Object)null))
					{
						sE_Energy.ApplyEnergyLossFromStamina(v);
					}
				}
			}
		}
	}
	internal class Player_SetSleeping
	{
		[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(1)]
		[HarmonyPatch(typeof(Player), "SetSleeping")]
		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(0)]
		public static class Player_SetSleeping_Patches
		{
			[HarmonyPriority(700)]
			public static void Prefix(Player __instance, bool sleep, out bool __state)
			{
				__state = __instance.m_sleeping != sleep;
			}

			[HarmonyPriority(700)]
			public static void Postfix(Player __instance, bool __state)
			{
				if (__state)
				{
					SE_Energy sE_Energy = ((Character)__instance).m_seman.GetStatusEffect(SE_Energy.Hash) as SE_Energy;
					if (!((Object)(object)sE_Energy == (Object)null))
					{
						sE_Energy.ApplyEnergyGainFromSleeping();
					}
				}
			}
		}
	}
	internal class Player_UpdateEnvStatusEffects
	{
		[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(1)]
		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(0)]
		[HarmonyPatch(typeof(Player), "UpdateEnvStatusEffects")]
		public static class Player_UpdateEnvStatusEffects_Patches
		{
			[HarmonyPriority(700)]
			public static void Postfix(Player __instance, float dt)
			{
				if (!((Character)__instance).InIntro())
				{
					HandlePlayerStats(__instance);
				}
			}

			public static void HandlePlayerStats(Player player)
			{
				if (!((Character)player).m_seman.HaveStatusEffect(SE_PlayerStats.Hash))
				{
					((Character)player).m_seman.AddStatusEffect(SE_PlayerStats.Hash, false, 0, 0f);
					Main.LogMessage("Environment Status (invisible SE) applied to player.");
				}
			}
		}
	}
	internal class Player_UpdateFood
	{
		[HarmonyPatch(typeof(Player), "UpdateFood")]
		public static class Player_UpdateFood_Patches
		{
			[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(1)]
			[HarmonyPriority(700)]
			public static void Postfix(Player __instance)
			{
				if (!((Character)__instance).InIntro() && __instance.GetPlayerID() != 0 && ConfigManager.HungerEnabled.Value)
				{
					if (__instance.m_foods.Count == 0 && !((Character)__instance).m_seman.HaveStatusEffect(SE_Hungry.Hash))
					{
						((Character)__instance).m_seman.AddStatusEffect(SE_Hungry.Hash, false, 0, 0f);
					}
					if (__instance.m_foods.Count > 0 && ((Character)__instance).m_seman.HaveStatusEffect(SE_Hungry.Hash))
					{
						((Character)__instance).m_seman.RemoveStatusEffect(SE_Hungry.Hash, false);
					}
				}
			}
		}
	}
	internal class Tutorial_Awake
	{
		[HarmonyPatch(typeof(Tutorial), "Awake")]
		public static class Tutorial_Awake_Patches
		{
			[HarmonyPriority(700)]
			[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(1)]
			public static void Postfix(Tutorial __instance)
			{
				TutorialText[] tutorialTexts = Main.GetInstance().TutorialTexts;
				foreach (TutorialText val in tutorialTexts)
				{
					if (!__instance.m_texts.Contains(val))
					{
						Main.LogMessage("Adding tutorial " + val.m_name);
						__instance.m_texts.Add(val);
					}
				}
			}
		}
	}
}
namespace EnvironmentalAwareness.Data
{
	[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(0)]
	[<83504f54-6e47-40a8-83ac-fc458bfe811e>NullableContext(2)]
	public class ConfigManager
	{
		public static ConfigSync configSync;

		public static ConfigEntry<bool> DebugLogging;

		public static ConfigEntry<bool> VitalityEnabled;

		public static ConfigEntry<bool> EnergyEnabled;

		public static ConfigEntry<bool> HungerEnabled;

		public static ConfigEntry<float> NewPlayerCooldown;

		public static ConfigEntry<bool> DeathGrantsImmunity;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(new byte[] { 2, 1 })]
		public static ConfigEntry<string> GlobalKeySpring;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(new byte[] { 2, 1 })]
		public static ConfigEntry<string> GlobalKeySummer;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(new byte[] { 2, 1 })]
		public static ConfigEntry<string> GlobalKeyFall;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(new byte[] { 2, 1 })]
		public static ConfigEntry<string> GlobalKeyWinter;

		public static ConfigEntry<float> VColdAdd;

		public static ConfigEntry<float> VFreezingAdd;

		public static ConfigEntry<float> VWetAdd;

		public static ConfigEntry<float> VColdWetMultiplier;

		public static ConfigEntry<float> VFreezingWetMultiplier;

		public static ConfigEntry<float> VHungerAdd;

		public static ConfigEntry<float> VHPDamageAdd;

		public static ConfigEntry<float> VPoisonDamageAdd;

		public static ConfigEntry<float> VBurningDamageAdd;

		public static ConfigEntry<float> VShockDamageAdd;

		public static ConfigEntry<float> VFrostDamageAdd;

		public static ConfigEntry<float> VAshlandsPassiveAdd;

		public static ConfigEntry<float> VDeepNorthPassiveAdd;

		[<ea518f4f-51c4-47f8-b97f-a8a02765119d>Nullable(new byte[] { 2, 1 })]
		public static ConfigEntry<string> VEnvironmentsToIgnore;

		public static ConfigEntry<float> VSpringSeasonalMultiplier;

		public static ConfigEntry<float> VSummerSeasonalMultiplier;

		public static ConfigEntry<float> VFallSeasonalMultiplier;

		public static ConfigEntry<float> VWinterSeasonalMultiplier;

		public static ConfigEntry<float> VHeatRemove;

		public static ConfigEntry<float> VShelteredRemove;

		public static ConfigEntry<float> VHeatShelteredMultiplier;

		public static ConfigEntry<float> VRestingRemove;

		public static ConfigEntry<float> VRestedRemove;

		public static ConfigEntry<float> VPassiveRemove;

		public static ConfigEntry<float> VHealthPotionRemove;

		public static ConfigEntry<float> VResistancePerArmorPoint;

		public static ConfigEntry<int> VResistanceMinArmorThreshold;

		public static ConfigEntry<float> VPoisonResistantMultiplier;

		public static ConfigEntry<float> VPoisonVeryResistantMultiplier;

		public static ConfigEntry<float> VFireResistantMultiplier;

		public static ConfigEntry<float> VFireVeryResistantMultiplier;

		public static ConfigEntry<float> VLightningResistantMultiplier;

		public static ConfigEntry<float> VLightningVeryResistantMultiplier;

		public static ConfigEntry<float> VFrostResistantMultiplier;

		public static ConfigEntry<float> VFrostVeryResistantMultiplier;

		public static ConfigEntry<float> VMultiplierPer10FoodValue;

		public static ConfigEntry<bool> VHealthDamageEnabled;

		public static ConfigEntry<float> VHealthMaxDamageOverTime;

		public static ConfigEntry<float> VHealthMaxRegenReduction;

		public static ConfigEntry<float> VHealthDamageMinStartThreshold;

		public static ConfigEntry<bool> VMoveSpeedReductionEnabled;

		public static ConfigEntry<float> VMoveSpeedMaxReduction;

		public static ConfigEntry<float> VMoveSpeedMinStartThreshold;

		public static ConfigEntry<bool> VStaminaRegenReductionEnabled;

		public static ConfigEntry<float> VStaminaRegenMaxReduction;

		public static ConfigEntry<float> VStaminaRegenReductionThreshold;

		public static ConfigEntry<bool> VFoodBurnRateEnabled;

		public static ConfigEntry<float> VFoodBurnMaxOverTime;

		public static ConfigEntry<float> VFoodBurnMinStartThreshold;

		public static ConfigEntry<bool> VFoodBurnStatReduction;

		public static ConfigEntry<bool> VPhysicalWeaknessEnabled;

		public static ConfigEntry<float> VPhysicalWeaknessThreshold;

		public static ConfigEntry<bool> VElementalWeaknessEnabled;

		public static ConfigEntry<float> VElementalWeaknessThreshold;

		public static ConfigEntry<float> ELossStaminaPointUsedAdd;

		public static ConfigEntry<float> ELossMotionAdd;

		public static ConfigEntry<float> ELossHungryAdd;

		public static ConfigEntry<float> ELossColdAdd;

		public static ConfigEntry<float> ELossFreezingAdd;

		public static ConfigEntry<float> ELossWetAdd;

		public static ConfigEntry<float> ELossHeavyLoadAdd;

		public static ConfigEntry<float> ELossHeavyLoadThreshold;

		public static ConfigEntry<float> ELossNoRestMultiplier;

		public static ConfigEntry<float> ELossNoRestThreshold;

		public static ConfigEntry<float> ESpringSeasonMultiplier;

		public static ConfigEntry<float> ESummerSeasonMultiplier;

		public static ConfigEntry<float> EFallSeasonMultiplier;

		public static ConfigEntry<float> EWinterSeasonMultiplier;

		public static ConfigEntry<float> ELossSittingRemove;

		public static ConfigEntry<float> ELossRestingRemove;

		public static ConfigEntry<float> ELossSittingRestingMultiplier;

		public static ConfigEntry<float> ELossSittingRestingShelterMultiplier;

		public static ConfigEntry<float> ELossRestedRemove;

		public static ConfigEntry<float> ELossPercentageSleepRemove;

		public static ConfigEntry<float> ELossFoodStaminaRemove;

		public static ConfigEntry<float> ELossStaminaMeadRemove;

		public static ConfigEntry<float> ELossRestedResist;

		public static ConfigEntry<float> ELossStaminaMeadResist;

		public static ConfigEntry<float> ELossLowEnergyResist;

		public static ConfigEntry<float> ELossLowEnergyThreshold;

		public static ConfigEntry<bool> EDamageReductionEnabled;

		public static ConfigEntry<float> EDamageMaxReduction;

		public static ConfigEntry<float> EDamageReductionThreshold;

		public static ConfigEntry<bool> ESkillGainReductionEnabled;

		public static ConfigEntry<float> ESkillGainMaxReduction;

		public static ConfigEntry<float> ESkillGainReductionThreshold;

		public static Co