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

plugins/EnvironmentalAwareness.dll

Decompiled 8 hours 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.Reflection.Emit;
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 UnityEngine.SceneManagement;
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]
	[<b8e33d13-0cae-4335-9690-1f64cece8a72>Embedded]
	internal sealed class <b8e33d13-0cae-4335-9690-1f64cece8a72>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]
	[<b8e33d13-0cae-4335-9690-1f64cece8a72>Embedded]
	internal sealed class <b743f850-bec7-468a-9daa-3c17ad10c240>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <b743f850-bec7-468a-9daa-3c17ad10c240>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <b743f850-bec7-468a-9daa-3c17ad10c240>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	[<b8e33d13-0cae-4335-9690-1f64cece8a72>Embedded]
	internal sealed class <f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace EnvironmentalAwareness
{
	[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(1)]
	[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(0)]
	[BepInPlugin("maxfoxgaming.environmentalawareness", "EnvironmentalAwareness", "1.2.1")]
	public class Main : BaseUnityPlugin
	{
		public const string PluginGUID = "maxfoxgaming.environmentalawareness";

		public const string PluginName = "EnvironmentalAwareness";

		public const string PluginVersion = "1.2.1";

		public const string PluginSavePath = "EnvironmentalAwareness_";

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		private static Main instance;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public AssetBundle Bundle;

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

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

		[<b743f850-bec7-468a-9daa-3c17ad10c240>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 CapabilitySEName = "EA_Capability";

		public static readonly string PlayerStatsSEName = "EA_PlayerStats";

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public SE_Vitality Vitality;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public SE_Hungry Hungry;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public SE_Energy Energy;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public SE_Capability Capability;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public SE_PlayerStats PlayerStats;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public Skill Resistance;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public Skill Fitness;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public Skill Assurance;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public Skill Perseverence;

		public TutorialText[] TutorialTexts = (TutorialText[])(object)new TutorialText[7]
		{
			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"
			},
			new TutorialText
			{
				m_name = "EnvironmentalAwarenessPotentiality",
				m_label = "$ea_tutorial_potentiality_label",
				m_text = "$ea_tutorial_potentiality_text",
				m_topic = "$ea_tutorial_potentiality_topic"
			},
			new TutorialText
			{
				m_name = "EnvronmentalAwarenessPotentialityLow",
				m_label = "$ea_tutorial_potentiality_low_label",
				m_text = "$ea_tutorial_potentiality_low_text",
				m_topic = "$ea_tutorial_potentiality_low_topic"
			},
			new TutorialText
			{
				m_name = "EnvironmentalAwarenessCapability",
				m_label = "$ea_tutorial_capability_low_label",
				m_text = "$ea_tutorial_capability_low_text",
				m_topic = "$ea_tutorial_capability_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 and the save system.", "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);
			SetupWatcher();
			LoadAssets();
			InitializeSEs();
			InitializeSkills();
			Harmony val = harmony;
			if (val != null)
			{
				val.PatchAll();
			}
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, "maxfoxgaming.environmentalawareness.cfg");
			fileSystemWatcher.Changed += ConfigManager.OnConfigChangedFromFile;
			fileSystemWatcher.Created += ConfigManager.OnConfigChangedFromFile;
			fileSystemWatcher.Renamed += ConfigManager.OnConfigChangedFromFile;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		public void LoadAssets()
		{
			LogMessage("Loading bundles.");
			Bundle = LoadBundle("environmentalsprites");
		}

		public void InitializeSEs()
		{
			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;
			Capability = ScriptableObject.CreateInstance<SE_Capability>();
			((Object)Capability).name = CapabilitySEName;
			PlayerStats = ScriptableObject.CreateInstance<SE_PlayerStats>();
			((Object)PlayerStats).name = PlayerStatsSEName;
		}

		public void InitializeSkills()
		{
			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;
			Perseverence = new Skill("Perseverence", Bundle.LoadAsset<Sprite>("capabilityicon1"));
			Perseverence.SkillEffectFactor = ConfigManager.PerseverenceSkillMaxTimeGain.Value;
			Perseverence.SkillGainFactor = ConfigManager.PerseverenceSkillGainFactor.Value;
			Fitness.Configurable = false;
		}

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

		[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(2)]
		public static Main GetInstance()
		{
			return instance;
		}

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

		public static bool IsInMainScene()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			return ((Scene)(ref activeScene)).name.Equals("main");
		}

		[return: <b743f850-bec7-468a-9daa-3c17ad10c240>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;
		}
	}
	[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(1)]
	[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(0)]
	public class SE_Capability : SE_SurvivalBase
	{
		public int m_meadsConsumed = 0;

		public int m_maxMeadsConsumed = 6;

		public float m_capabilityPercFromMead = 0f;

		public float m_capabilityPercFromMeadTick = 0f;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_vitalityMaxModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_energyMaxModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_perserverenceSkillModifier;

		public WarningMessage c_warningTired = new WarningMessage("$ea_capability_warningmessage_tired");

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

		protected override string SENameKey => "$ea_se_capability";

		protected override string IconName => "capabilityicon";

		protected override int IconCount => 10;

		protected override string DataKey => "EnvironmentalAwareness_" + Main.CapabilitySEName;

		protected override string TooltipKey => "$ea_player_capability";

		protected override bool DisplayPercentageEnabledConfigEntry => ConfigManager.DisplayCapabilityPercentage.Value;

		protected override bool DisplayWarningTextsConfigEntry => ConfigManager.DisplayCapabilityWarningTexts.Value;

		protected override string[] Statuses => new string[5] { "$ea_capability_status_0", "$ea_capability_status_1", "$ea_capability_status_2", "$ea_capability_status_3", "$ea_capability_status_4" };

		protected override void SetupStatModifiers()
		{
			c_vitalityMaxModifier = new StatModifier(this, null, StatModifier.CalculationType.INVERSEPERCENTAGE)
			{
				m_enabled = ConfigManager.VitalityEnabled.Value,
				m_maxMultiplier = ConfigManager.CVitalityMaxCap.Value,
				m_threshold = ConfigManager.CVitalityMaxCapThreshold.Value,
				m_defaultValue = 100f
			};
			c_energyMaxModifier = new StatModifier(this, null, StatModifier.CalculationType.INVERSEPERCENTAGE)
			{
				m_enabled = ConfigManager.EnergyEnabled.Value,
				m_maxMultiplier = ConfigManager.CEnergyMaxCap.Value,
				m_threshold = ConfigManager.CEnergyMaxCapThreshold.Value,
				m_defaultValue = 100f
			};
			c_perserverenceSkillModifier = new StatModifier(this, c_warningTired, StatModifier.CalculationType.REGULAR)
			{
				m_enabled = ConfigManager.CapabilityEnabled.Value,
				m_maxMultiplier = ConfigManager.PerseverenceSkillGainFactor.Value,
				m_threshold = ConfigManager.PerseverenceSkillMinThreshold.Value,
				m_defaultValue = 0f
			};
		}

		public override void SetupBaseFields()
		{
			base.SetupBaseFields();
			m_baseMaxStatLoss = ConfigManager.CTimeToDrain.Value;
		}

		protected override void SetupExtraFields()
		{
			m_maxMeadsConsumed = ConfigManager.CTastyMeadLimit.Value;
		}

		protected override void LoadExtraFields(List<string> list)
		{
			list[4].AssignAsInt(out m_meadsConsumed);
			list[5].AssignAsFloat(out m_capabilityPercFromMead);
			list[6].AssignAsFloat(out m_capabilityPercFromMeadTick);
			list[7].AssignAsBool(out c_warningTired.m_display);
		}

		protected override void SaveExtraFields(StringBuilder sb)
		{
			sb.AppendStat(m_meadsConsumed);
			sb.AppendStat(m_capabilityPercFromMead);
			sb.AppendStat(m_capabilityPercFromMeadTick);
			sb.AppendStat(c_warningTired.m_display);
		}

		protected override void UpdateRealtimeExternalStatChanges(float dt)
		{
			UpdateCapabilityFromMead(dt);
			RaisePerserverenceSkill(dt);
		}

		private void UpdateCapabilityFromMead(float dt)
		{
			if ((double)m_capabilityPercFromMead < 0.01)
			{
				m_capabilityPercFromMead = 0f;
				m_capabilityPercFromMeadTick = 0f;
			}
			else
			{
				base.ChangeStatLossByPercentage(-1f * m_capabilityPercFromMeadTick);
				m_capabilityPercFromMead -= m_capabilityPercFromMeadTick;
			}
		}

		public void RaisePerserverenceSkill(float dt)
		{
			((Character)(object)player).RaiseSkill("Perseverence", 0.01f * dt * c_perserverenceSkillModifier.CalculateMultiplier());
		}

		protected override void UpdateTutorial()
		{
			if (m_statLossPerc > 60f)
			{
				player.ShowTutorial("EnvironmentalAwarenessCapability", false);
			}
		}

		protected override void UpdateStatValue()
		{
			m_statLoss = Mathf.Clamp(m_statLoss + m_statChange, 0f, m_maxStatLoss);
		}

		public override void Recalculate()
		{
			base.Recalculate();
			m_statChange = CalculateTotalMultiplier();
		}

		private float CalculateTotalMultiplier()
		{
			return CalculateVitalityMultiplier() * CalculateEnergyMultiplier() * CalculateRestedMultiplier();
		}

		private float CalculateVitalityMultiplier()
		{
			if (!ConfigManager.VitalityEnabled.Value)
			{
				return 1f;
			}
			float vitalityPercentage = pes.VitalityPercentage;
			if (vitalityPercentage >= ConfigManager.CVitalityResistThreshold.Value)
			{
				return ConfigManager.CVitalityResist.Value;
			}
			if (vitalityPercentage < ConfigManager.CLowVitalityLossThreshold.Value)
			{
				return ConfigManager.CLowVitalityLoss.Value;
			}
			return 1f;
		}

		private float CalculateEnergyMultiplier()
		{
			if (!ConfigManager.EnergyEnabled.Value)
			{
				return 1f;
			}
			float energyPercentage = pes.EnergyPercentage;
			if (energyPercentage >= ConfigManager.CEnergyResistThreshold.Value)
			{
				return ConfigManager.CEnergyResist.Value;
			}
			if (energyPercentage < ConfigManager.CLowEnergyLossThreshold.Value)
			{
				return ConfigManager.CLowEnergyLoss.Value;
			}
			return 1f;
		}

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

		protected override float CalculateAdditionalMaxStat()
		{
			float num = pes.PerseverenceSkillLevel / 100f;
			return num * ConfigManager.PerseverenceSkillMaxTimeGain.Value;
		}

		protected override void UpdateEffects()
		{
			UpdateStatusEffectModifiers();
		}

		private void UpdateStatusEffectModifiers()
		{
			pes.VitalityMaxPercentage = c_vitalityMaxModifier.CalculateMultiplier();
			pes.EnergyMaxPercentage = c_energyMaxModifier.CalculateMultiplier();
		}

		public void ApplyCapabilityGainFromMead()
		{
			if (IncreaseMeadConsumption())
			{
				m_capabilityPercFromMead += ConfigManager.CTastyMeadLossRemove.Value;
				m_capabilityPercFromMeadTick = ConfigManager.CTastyMeadLossRemove.Value / 100f;
			}
		}

		public void ApplyCapabilityGainFromSleep()
		{
			base.ChangeStatLossByPercentage(-1f * ConfigManager.CSleepLossRemove.Value);
			DecreaseMeadConsumption();
		}

		private bool IncreaseMeadConsumption()
		{
			if (m_meadsConsumed >= m_maxMeadsConsumed)
			{
				return false;
			}
			m_meadsConsumed++;
			return true;
		}

		private void DecreaseMeadConsumption()
		{
			m_meadsConsumed = Mathf.Max(m_meadsConsumed - ConfigManager.CTastyMeadSleepRemove.Value, 0);
		}

		protected override void LogStatistics()
		{
			Main.LogMessage("Capability SE UPDATE");
			Main.LogMessage("Capability: " + Mathf.Round(100f - m_statLossPerc) + "( " + (m_maxStatLoss - m_statLoss) + " / " + m_maxStatLoss + ")");
			Main.LogMessage("Change OT: " + m_statChange);
		}

		public override void GetAdditionalDebugStrings(StringBuilder sb)
		{
			base.GetAdditionalDebugStrings(sb);
			sb.AppendFormat("m_meadsConsumed: {0}\n", m_meadsConsumed);
			sb.AppendFormat("m_maxMeadsConsumed: {0}\n", m_maxMeadsConsumed);
			sb.AppendFormat("m_capabilityPercFromMead: {0}\n", m_capabilityPercFromMead);
			sb.AppendFormat("m_capabilityPercFromMeadTick: {0}\n", m_capabilityPercFromMeadTick);
		}
	}
	[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(0)]
	[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(1)]
	public class SE_Energy : SE_SurvivalBase
	{
		public float m_staminaRegenDelay = 0f;

		public float m_staminaReductionMultiplier = 1f;

		public float m_energyFromFood = 0f;

		public float m_energyFromFoodTick = 0f;

		public float m_energyRegenSpeed = 0.5f;

		public float m_timeSinceRested = 0f;

		public float m_fitnessSkillMultiplier = 1f;

		public float m_seasonMultiplier = 1f;

		public float m_lossEnergyRestedMult = 1f;

		public float m_lossEnergyCarryWeightAdd = 0f;

		public float m_lossEnergyMovementAdd = 0f;

		public float m_staminaMeadMult = 1f;

		public float m_noRestMultiplier = 1f;

		public float s_totalStaminaUseInCycle = 0f;

		public float s_totalEnergyUseInCycle = 0f;

		public float s_lastRawLossInCycle;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_carryWeightModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_restedRemoveModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_damageModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_speedModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_skillGainModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_staminaReductionModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_staminaRegenModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_staminaDelayModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_energyLossResistModifier;

		public WarningMessage c_warningWeight = new WarningMessage("$ea_energy_warningmessage_weight");

		public WarningMessage c_warningDamage = new WarningMessage("$ea_energy_warningmessage_damage");

		public WarningMessage c_warningSpeed = new WarningMessage("$ea_energy_warningmessage_movement");

		public WarningMessage c_warningSkillGain = new WarningMessage("$ea_energy_warningmessage_skillgain");

		public WarningMessage c_warningStaminaReduction = new WarningMessage("$ea_energy_warningmessage_maxstamina");

		public WarningMessage c_warningStaminaRegen = new WarningMessage("$ea_energy_warningmessage_staminaregen");

		public WarningMessage c_warningStaminaDelay = new WarningMessage("$ea_energy_warningmessage_staminadelay");

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

		protected override string SENameKey => "$ea_se_energy";

		protected override string IconName => "energyicon";

		protected override int IconCount => 15;

		protected override string DataKey => "EnvironmentalAwareness_" + Main.EnergySEName;

		protected override string TooltipKey => "$ea_player_energy";

		protected override bool DisplayPercentageEnabledConfigEntry => ConfigManager.DisplayEnergyPercentage.Value;

		protected override bool DisplayWarningTextsConfigEntry => ConfigManager.DisplayEnergyWarningTexts.Value;

		protected override 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" };

		protected override void SetupStatModifiers()
		{
			c_carryWeightModifier = new StatModifier(this, c_warningWeight, StatModifier.CalculationType.REGULAR)
			{
				m_enabled = true,
				m_maxMultiplier = ConfigManager.ELossHeavyLoadAdd.Value,
				m_threshold = ConfigManager.ELossHeavyLoadThreshold.Value,
				m_defaultValue = 0f
			};
			c_restedRemoveModifier = new StatModifier(this, null, StatModifier.CalculationType.ONEZERO)
			{
				m_enabled = ConfigManager.ERestedLossEnabled.Value,
				m_maxMultiplier = 1f,
				m_threshold = ConfigManager.ERestedLossThreshold.Value,
				m_defaultValue = 0f
			};
			c_damageModifier = new StatModifier(this, c_warningDamage, StatModifier.CalculationType.INVERSE)
			{
				m_enabled = ConfigManager.EDamageReductionEnabled.Value,
				m_maxMultiplier = ConfigManager.EDamageMaxReduction.Value,
				m_threshold = ConfigManager.EDamageReductionThreshold.Value,
				m_defaultValue = 1f
			};
			c_speedModifier = new StatModifier(this, c_warningSpeed, StatModifier.CalculationType.NEGATIVE)
			{
				m_enabled = ConfigManager.EMoveSpeedReductionEnabled.Value,
				m_maxMultiplier = ConfigManager.EMoveSpeedMaxReduction.Value,
				m_threshold = ConfigManager.EMoveSpeedReductionMinThreshold.Value,
				m_defaultValue = 0f
			};
			c_skillGainModifier = new StatModifier(this, c_warningSkillGain, StatModifier.CalculationType.NEGATIVE)
			{
				m_enabled = ConfigManager.ESkillGainReductionEnabled.Value,
				m_maxMultiplier = ConfigManager.EMoveSpeedMaxReduction.Value,
				m_threshold = ConfigManager.EMoveSpeedReductionMinThreshold.Value,
				m_defaultValue = 0f
			};
			c_staminaReductionModifier = new StatModifier(this, c_warningStaminaReduction, StatModifier.CalculationType.INVERSE)
			{
				m_enabled = ConfigManager.EMaxStaminaReductionEnabled.Value,
				m_maxMultiplier = ConfigManager.EMaxStaminaReduction.Value,
				m_threshold = ConfigManager.EMaxStaminaReductionThreshold.Value,
				m_defaultValue = 1f
			};
			c_staminaRegenModifier = new StatModifier(this, c_warningStaminaRegen, StatModifier.CalculationType.INVERSE)
			{
				m_enabled = ConfigManager.EStaminaRegenEnabled.Value,
				m_maxMultiplier = ConfigManager.EStaminaRegenMaxReduction.Value,
				m_threshold = ConfigManager.EStaminaRegenMinThreshold.Value,
				m_defaultValue = 1f
			};
			c_staminaDelayModifier = new StatModifier(this, c_warningStaminaDelay, StatModifier.CalculationType.REGULAR)
			{
				m_enabled = ConfigManager.EStaminaRegenDelayEnabled.Value,
				m_maxMultiplier = ConfigManager.EStaminaRegenDelayMaxMultiplier.Value,
				m_threshold = ConfigManager.EStaminaRegenDelayMinThreshold.Value,
				m_defaultValue = 0f
			};
			c_energyLossResistModifier = new StatModifier(this, null, StatModifier.CalculationType.INVERSE)
			{
				m_enabled = true,
				m_maxMultiplier = ConfigManager.ELossLowEnergyResist.Value,
				m_threshold = ConfigManager.ELossLowEnergyThreshold.Value,
				m_defaultValue = 1f
			};
		}

		protected override void SetupExtraFields()
		{
			//IL_0007: 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)
			((SE_Stats)this).m_modifyAttackSkill = (SkillType)999;
			((SE_Stats)this).m_raiseSkill = (SkillType)999;
			((SE_Stats)this).m_raiseSkillModifier = 0f;
			m_staminaRegenDelay = 0f;
			m_staminaReductionMultiplier = 1f;
			m_seasonMultiplier = 1f;
			m_lossEnergyRestedMult = 1f;
			m_lossEnergyCarryWeightAdd = 0f;
			m_lossEnergyMovementAdd = 0f;
			m_staminaMeadMult = 1f;
			m_noRestMultiplier = 1f;
		}

		protected override void LoadExtraFields(List<string> list)
		{
			list[4].AssignAsFloat(out m_staminaRegenDelay);
			list[5].AssignAsFloat(out m_staminaReductionMultiplier);
			list[6].AssignAsFloat(out m_energyFromFood);
			list[7].AssignAsFloat(out m_energyFromFoodTick);
			list[8].AssignAsFloat(out m_energyRegenSpeed);
			list[9].AssignAsFloat(out m_timeSinceRested);
			list[10].AssignAsFloat(out m_fitnessSkillMultiplier);
			list[11].AssignAsFloat(out m_seasonMultiplier);
			list[12].AssignAsFloat(out m_lossEnergyRestedMult);
			list[13].AssignAsFloat(out m_lossEnergyCarryWeightAdd);
			list[14].AssignAsFloat(out m_lossEnergyMovementAdd);
			list[15].AssignAsFloat(out m_staminaMeadMult);
			list[16].AssignAsFloat(out m_noRestMultiplier);
			list[17].AssignAsBool(out c_warningSpeed.m_display);
			list[18].AssignAsBool(out c_warningStaminaRegen.m_display);
			list[19].AssignAsBool(out c_warningStaminaDelay.m_display);
			list[20].AssignAsBool(out c_warningSkillGain.m_display);
			list[21].AssignAsBool(out c_warningStaminaReduction.m_display);
			list[22].AssignAsBool(out c_warningDamage.m_display);
			list[23].AssignAsBool(out c_warningWeight.m_display);
		}

		protected override void SaveExtraFields(StringBuilder sb)
		{
			sb.AppendStat(m_staminaRegenDelay);
			sb.AppendStat(m_staminaReductionMultiplier);
			sb.AppendStat(m_energyFromFood);
			sb.AppendStat(m_energyFromFoodTick);
			sb.AppendStat(m_energyRegenSpeed);
			sb.AppendStat(m_timeSinceRested);
			sb.AppendStat(m_fitnessSkillMultiplier);
			sb.AppendStat(m_seasonMultiplier);
			sb.AppendStat(m_lossEnergyRestedMult);
			sb.AppendStat(m_lossEnergyCarryWeightAdd);
			sb.AppendStat(m_lossEnergyMovementAdd);
			sb.AppendStat(m_staminaMeadMult);
			sb.AppendStat(m_noRestMultiplier);
			sb.AppendStat(c_warningSpeed.m_display);
			sb.AppendStat(c_warningStaminaRegen.m_display);
			sb.AppendStat(c_warningStaminaDelay.m_display);
			sb.AppendStat(c_warningSkillGain.m_display);
			sb.AppendStat(c_warningStaminaReduction.m_display);
			sb.AppendStat(c_warningDamage.m_display);
			sb.AppendStat(c_warningWeight.m_display);
		}

		protected override void GetPlayerHintStrings(StringBuilder sb)
		{
			if (pes.EnergyMaxPercentage <= 99f)
			{
				sb.AppendFormat("$ea_player_energy_capped \n", Mathf.RoundToInt(pes.EnergyMaxPercentage));
			}
			if (pes.PlayerStaminaMead)
			{
				sb.Append("$ea_player_stamina_mead \n");
			}
			if (m_energyFromFood > 0f)
			{
				sb.Append("$ea_player_food_recover_energy \n");
			}
			if (m_timeSinceRested > ConfigManager.ELossNoRestThreshold.Value / 2f)
			{
				sb.Append("$ea_player_need_rest_energy \n");
			}
			if (m_statLossPerc > ConfigManager.ERestedLossThreshold.Value)
			{
				sb.Append("$ea_player_cannot_stay_rested \n");
			}
		}

		protected override void GetStatLossHintStrings(StringBuilder sb)
		{
			if (pes.PlayerCold || pes.PlayerFreezing)
			{
				sb.Append("$ea_player_coldfreezing_energy \n");
			}
			if (pes.PlayerWet)
			{
				sb.Append("$ea_player_wet_energy \n");
			}
			if (pes.PlayerHungry)
			{
				sb.Append("$ea_player_hungry_energy \n");
			}
		}

		protected override void GetStatGainHintStrings(StringBuilder sb)
		{
			sb.Append("$ea_player_recovering_energy \n");
		}

		protected override void GetStatChangeStrings(StringBuilder sb)
		{
			if (m_staminaReductionMultiplier != 1f)
			{
				sb.AppendFormat("$ea_se_maxstaminamultiplier: <color=orange>{0}x</color> \n", Mathf.Floor(101f * m_staminaReductionMultiplier) / 100f);
			}
			if (m_staminaRegenDelay > 0f)
			{
				sb.AppendFormat("$ea_se_staminaregendelay: <color=orange>{0}s</color> \n", (Mathf.Floor(10f * m_staminaRegenDelay) / 10f).ToString("+0;-0"));
			}
			if (m_staminaMeadMult != 1f)
			{
				sb.AppendFormat("$ea_se_energylossresist: <color=green>{0}%</color> \n", Mathf.Floor(100f * m_staminaMeadMult));
			}
		}

		protected override void UpdateRealtimeExternalStatChanges(float dt)
		{
			UpdateStaminaRegenDelay();
			UpdateEnergyFromFood(dt);
		}

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

		private void UpdateEnergyFromFood(float dt)
		{
			if ((double)m_energyFromFood < 0.01)
			{
				m_energyFromFood = 0f;
				m_energyFromFoodTick = 0f;
				return;
			}
			m_energyFromFoodTick = m_maxStatLoss / m_baseMaxStatLoss * Mathf.Min(m_energyRegenSpeed, m_energyFromFood) * dt;
			Main.LogMessage("Energy tick: " + m_energyFromFoodTick);
			m_statLoss -= m_energyFromFoodTick;
			float num = (100f - pes.EnergyMaxPercentage) * m_maxStatLoss / 100f;
			if (m_statLoss < num)
			{
				m_statLoss = num;
			}
			m_energyFromFood -= m_energyFromFoodTick;
		}

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

		protected override void UpdatePerSecondStateChanges()
		{
			UpdateNonRestedState();
			UpdateMovementState();
		}

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

		private void UpdateMovementState()
		{
			m_lossEnergyMovementAdd = (pes.PlayerMoving ? (m_noRestMultiplier * m_seasonMultiplier * m_fitnessSkillMultiplier * m_lossEnergyRestedMult * ConfigManager.ELossMotionAdd.Value) : 0f);
		}

		protected override void UpdateStatValue()
		{
			float num = c_energyLossResistModifier.CalculateMultiplier() * (m_statChange + m_lossEnergyMovementAdd);
			m_statLoss = Mathf.Clamp(m_statLoss + num, 0f, m_maxStatLoss);
			m_statLoss = Mathf.Max((100f - pes.EnergyMaxPercentage) * m_maxStatLoss / 100f, m_statLoss);
		}

		public override void Recalculate()
		{
			base.Recalculate();
			m_lossEnergyRestedMult = CalculateRestedMultiplier();
			m_lossEnergyCarryWeightAdd = CalculateCarryWeightAdd();
			m_seasonMultiplier = CalculateSeasonMultiplier();
			m_staminaMeadMult = CalculateStaminaMeadMultiplier();
			m_fitnessSkillMultiplier = CalculateFitnessSkillMultiplier();
			m_statChange = m_staminaMeadMult * m_seasonMultiplier * m_fitnessSkillMultiplier * CalculatePassiveLosses() - (CalculateGainsFromRest() + CalculateGainsFromStaminaMead());
		}

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

		private float CalculateCarryWeightAdd()
		{
			return c_carryWeightModifier.CalculateMultiplier(pes.PlayerCarryWeightPerc);
		}

		private 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 m_lossEnergyRestedMult * num;
		}

		private 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_maxStatLoss / m_baseMaxStatLoss * num;
		}

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

		protected override float CalculateAdditionalMaxStat()
		{
			float num = pes.FitnessSkillLevel / 100f;
			float num2 = ConfigManager.FitnessSkillMaxEnergyGain.Value - m_baseMaxStatLoss;
			return num * num2;
		}

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

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

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

		protected override void UpdateEffects()
		{
			UpdateRemoveRested();
			UpdateStatusEffectModifiers();
		}

		private void UpdateRemoveRested()
		{
			if (c_restedRemoveModifier.CalculateMultiplier() > 0f && 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);
				}
			}
		}

		private void UpdateStatusEffectModifiers()
		{
			((SE_Stats)this).m_damageModifier = c_damageModifier.CalculateMultiplier();
			((SE_Stats)this).m_speedModifier = c_speedModifier.CalculateMultiplier();
			((SE_Stats)this).m_raiseSkillModifier = c_skillGainModifier.CalculateMultiplier();
			m_staminaReductionMultiplier = c_staminaReductionModifier.CalculateMultiplier();
			((SE_Stats)this).m_staminaRegenMultiplier = c_staminaRegenModifier.CalculateMultiplier();
			m_staminaRegenDelay = c_staminaDelayModifier.CalculateMultiplier();
		}

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

		public void ApplyEnergyGainFromSleeping()
		{
			base.ChangeStatLossByPercentage(-1f * ConfigManager.ELossPercentageSleepRemove.Value);
		}

		public void ApplyEnergyLossFromStamina(float stamina)
		{
			if (!pes.PlayerNoSkillDrain && !(countdownTimer > 0f))
			{
				float num = stamina * (ConfigManager.ELossStaminaPointUsedAdd.Value + m_lossEnergyCarryWeightAdd);
				float num2 = m_lossEnergyRestedMult * m_seasonMultiplier * m_fitnessSkillMultiplier * m_noRestMultiplier * (1f - pes.FitnessSkillFactor) * num;
				m_statLoss += num2;
				if (m_statLoss > m_maxStatLoss)
				{
					num = m_statLoss - m_maxStatLoss;
					m_statLoss = m_maxStatLoss;
				}
				RaiseFitnessSkill(num);
				s_totalStaminaUseInCycle += stamina;
				s_totalEnergyUseInCycle += num2;
				s_lastRawLossInCycle = num;
			}
		}

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

		protected override void LogStatistics()
		{
			Main.LogMessage("ENERGY SE UPDATE");
			Main.LogMessage("Energy: " + Mathf.Round(100f - m_statLossPerc) + "( " + (m_maxStatLoss - m_statLoss) + " / " + m_maxStatLoss + ")");
			Main.LogMessage("Rested Resist Mult: " + m_lossEnergyRestedMult);
			Main.LogMessage("No Rested Debuffs: +" + m_noRestMultiplier + "x (" + m_timeSinceRested + "s since last rested)");
			Main.LogMessage("Stamina Regen Multiplier: " + ((SE_Stats)this).m_staminaRegenMultiplier + "x");
			Main.LogMessage("Stamina Regen Delay: +" + m_staminaRegenDelay + "s");
			Main.LogMessage("Seasonal Multiplier: " + m_seasonMultiplier + "x");
			Main.LogMessage("Fitness Skill Multiplier " + m_fitnessSkillMultiplier + "x");
			Main.LogMessage("Stamina Use in Cycle: " + s_totalStaminaUseInCycle);
			Main.LogMessage("Energy Loss from Stamina in Cycle: " + s_totalEnergyUseInCycle);
			Main.LogMessage("Last Raw Loss in Cycle: " + s_lastRawLossInCycle);
		}

		protected override void ResetCycleStats()
		{
			s_totalStaminaUseInCycle = 0f;
			s_totalEnergyUseInCycle = 0f;
			s_lastRawLossInCycle = 0f;
		}

		public override void GetAdditionalDebugStrings(StringBuilder sb)
		{
			base.GetAdditionalDebugStrings(sb);
			sb.AppendFormat("m_staminaRegenDelay: {0}\n", m_staminaRegenDelay);
			sb.AppendFormat("m_staminaReductionMultiplier: {0}\n", m_staminaReductionMultiplier);
			sb.AppendFormat("m_energyFromFood: {0}\n", m_energyFromFood);
			sb.AppendFormat("m_energyFromFoodTick: {0}\n", m_energyFromFoodTick);
			sb.AppendFormat("m_energyRegenSpeed: {0}\n", m_energyRegenSpeed);
			sb.AppendFormat("m_timeSinceRested: {0}\n", m_timeSinceRested);
			sb.AppendFormat("m_fitnessSkillMultiplier: {0}\n", m_fitnessSkillMultiplier);
			sb.AppendFormat("m_seasonMultiplier: {0}\n", m_seasonMultiplier);
			sb.AppendFormat("m_lossEnergyRestedMult: {0}\n", m_lossEnergyRestedMult);
			sb.AppendFormat("m_lossEnergyCarryWeightAdd: {0}\n", m_lossEnergyCarryWeightAdd);
			sb.AppendFormat("m_lossEnergyMovementAdd: {0}\n", m_lossEnergyMovementAdd);
			sb.AppendFormat("m_staminaMeadMult: {0}\n", m_staminaMeadMult);
			sb.AppendFormat("m_noRestMultiplier: {0}\n", m_noRestMultiplier);
		}
	}
	[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(0)]
	[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(1)]
	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();
		}
	}
	[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(1)]
	[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(0)]
	public class SE_PlayerStats : StatusEffect
	{
		[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(0)]
		private delegate void HandleSurvivalSEs();

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public Player player;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		private HandleSurvivalSEs HandleSurvivalSE;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		private SE_Vitality vitality;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		private SE_Energy energy;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		private SE_Capability capability;

		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 float perseverence_skill_level;

		private float perseverence_skill_factor;

		private float vitality_max_percentage = 100f;

		private float energy_max_percentage = 100f;

		private bool recalculate = false;

		public float lastUpdateTime = 0f;

		public float lastLogTime = 0f;

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

		[<b743f850-bec7-468a-9daa-3c17ad10c240>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 float PerseverenceSkillLevel
		{
			get
			{
				return perseverence_skill_level;
			}
			set
			{
				if (perseverence_skill_level != value)
				{
					Main.LogMessage("Change to perseverence skill level: " + value);
					perseverence_skill_level = value;
					recalculate = true;
				}
			}
		}

		public float PerseverenceSkillFactor
		{
			get
			{
				return perseverence_skill_factor;
			}
			set
			{
				if (perseverence_skill_factor != value)
				{
					Main.LogMessage("Change to perseverence skill factor.");
					perseverence_skill_factor = value;
				}
			}
		}

		public float VitalityPercentage
		{
			get
			{
				if ((Object)(object)vitality == (Object)null)
				{
					return 100f;
				}
				return 100f - vitality.m_statLossPerc;
			}
		}

		public float EnergyPercentage
		{
			get
			{
				if ((Object)(object)energy == (Object)null)
				{
					return 100f;
				}
				return 100f - energy.m_statLossPerc;
			}
		}

		public float VitalityMaxPercentage
		{
			get
			{
				return vitality_max_percentage;
			}
			set
			{
				vitality_max_percentage = Mathf.Clamp(value, 0f, 100f);
			}
		}

		public float EnergyMaxPercentage
		{
			get
			{
				return energy_max_percentage;
			}
			set
			{
				energy_max_percentage = Mathf.Clamp(value, 0f, 100f);
			}
		}

		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>>();
			HandleStatusEffectSetup();
		}

		public void HandleStatusEffectSetup()
		{
			if (ConfigManager.VitalityEnabled.Value)
			{
				HandleSurvivalSE = (HandleSurvivalSEs)Delegate.Combine(HandleSurvivalSE, new HandleSurvivalSEs(HandleVitality));
			}
			else
			{
				FlashStatusEffect<SE_Vitality>(SE_Vitality.Hash);
			}
			if (ConfigManager.EnergyEnabled.Value)
			{
				HandleSurvivalSE = (HandleSurvivalSEs)Delegate.Combine(HandleSurvivalSE, new HandleSurvivalSEs(HandleEnergy));
			}
			else
			{
				FlashStatusEffect<SE_Energy>(SE_Energy.Hash);
			}
			if (ConfigManager.CapabilityEnabled.Value)
			{
				HandleSurvivalSE = (HandleSurvivalSEs)Delegate.Combine(HandleSurvivalSE, new HandleSurvivalSEs(HandleCapability));
			}
			else
			{
				FlashStatusEffect<SE_Capability>(SE_Capability.Hash);
			}
		}

		public void CleanupAndRemoveSurvivalEffects()
		{
			SaveAndRemoveStatusEffect<SE_Vitality>(SE_Vitality.Hash);
			SaveAndRemoveStatusEffect<SE_Energy>(SE_Energy.Hash);
			SaveAndRemoveStatusEffect<SE_Capability>(SE_Capability.Hash);
			((Character)player).m_seman.RemoveStatusEffect((StatusEffect)(object)this, false);
		}

		public override bool IsDone()
		{
			return false;
		}

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

		[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(0)]
		public void SaveAndRemoveStatusEffect<T>(int hash) where T : SE_SurvivalBase
		{
			if (!((Character)player).m_seman.HaveStatusEffect(hash))
			{
				Main.LogMessage("Player does not have " + typeof(T).ToString() + " for save.");
				return;
			}
			T val = ((Character)player).m_seman.GetStatusEffect(hash) as T;
			if ((Object)(object)val == (Object)null)
			{
				Main.LogMessage("Cannot find status effect of type " + typeof(T).ToString());
				return;
			}
			val.SaveData();
			((Character)player).m_seman.RemoveStatusEffect(hash, false);
		}

		[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(0)]
		public void FlashStatusEffect<T>(int hash) where T : SE_SurvivalBase
		{
			if (!((Character)player).m_seman.HaveStatusEffect(hash))
			{
				((Character)player).m_seman.AddStatusEffect(hash, false, 0, 0f);
				Main.LogMessage("Added " + typeof(T).ToString() + " for flash");
			}
			T val = ((Character)player).m_seman.GetStatusEffect(hash) as T;
			if ((Object)(object)val == (Object)null)
			{
				Main.LogMessage("Cannot find status effect of type " + typeof(T).ToString());
				return;
			}
			val.ClearSaveData();
			val.SetupBaseFields();
			val.Recalculate();
			((Character)player).m_seman.RemoveStatusEffect(hash, false);
		}

		public void HandleVitality()
		{
			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 (!((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;
			energy = ((seman != null) ? seman.GetStatusEffect(SE_Energy.Hash) : null) as SE_Energy;
			if ((Object)(object)energy != (Object)null && ShouldRecalculate())
			{
				energy.Recalculate();
			}
		}

		public void HandleCapability()
		{
			if (!((Character)player).m_seman.HaveStatusEffect(SE_Capability.Hash))
			{
				((Character)player).m_seman.AddStatusEffect(SE_Capability.Hash, false, 0, 0f);
				Main.LogMessage("Capability status effect initialized");
			}
			SEMan seman = ((Character)player).m_seman;
			capability = ((seman != null) ? seman.GetStatusEffect(SE_Capability.Hash) : null) as SE_Capability;
			if ((Object)(object)capability != (Object)null && ShouldRecalculate())
			{
				capability.Recalculate();
			}
		}

		[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(2)]
		public bool TryGetVitalitySE(out SE_Vitality vitality)
		{
			vitality = this.vitality;
			return (Object)(object)vitality != (Object)null;
		}

		[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(2)]
		public bool TryGetEnergySE(out SE_Energy energy)
		{
			energy = this.energy;
			return (Object)(object)energy != (Object)null;
		}

		[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(2)]
		public bool TryGetCapabilitySE(out SE_Capability capability)
		{
			capability = this.capability;
			return (Object)(object)capability != (Object)null;
		}

		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");
			PerseverenceSkillLevel = GetSkillLevel("Perseverence");
			PerseverenceSkillFactor = GetSkillEffectFactor("Perseverence");
		}

		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);
		}
	}
	public class SE_Stats_Extended : SE_Stats
	{
		public float m_attackEitrUseModifier;

		[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(1)]
		public override string GetTooltipString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(((SE_Stats)this).GetTooltipString());
			if (m_attackEitrUseModifier != 0f)
			{
				stringBuilder.AppendFormat("$ea_se_attackeitr: <color=orange>{0}%</color>\n", (m_attackEitrUseModifier * 100f).ToString("+0;-0"));
			}
			return stringBuilder.ToString();
		}

		public virtual void ModifyAttackEitrUsage(float baseEitrUse, ref float eitrUse)
		{
			eitrUse += baseEitrUse * m_attackEitrUseModifier;
		}
	}
	[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(0)]
	[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(1)]
	public class SE_SurvivalBase : SE_Stats_Extended
	{
		[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(0)]
		public class StatModifier
		{
			public enum CalculationType
			{
				REGULAR,
				NEGATIVE,
				INVERSE,
				PLUSONESHIFT,
				PERCENTAGE,
				INVERSEPERCENTAGE,
				ONEZERO
			}

			[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(1)]
			public SE_SurvivalBase m_statusEffect;

			[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
			public WarningMessage m_warning;

			public CalculationType m_calculationType;

			public bool m_enabled = true;

			public float m_defaultValue = 0f;

			public float m_threshold = 0f;

			public float m_maxMultiplier = 1f;

			[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(1)]
			public StatModifier(SE_SurvivalBase m_statusEffect, [<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)] WarningMessage m_warning, CalculationType m_calculationType)
			{
				this.m_statusEffect = m_statusEffect;
				this.m_warning = m_warning;
				this.m_calculationType = m_calculationType;
			}

			public float CalculateMultiplier()
			{
				return CalculateMultiplier(m_statusEffect.m_statLossPerc);
			}

			public float CalculateMultiplier(float externalValue)
			{
				float defaultValue = m_defaultValue;
				if (!m_enabled)
				{
					return defaultValue;
				}
				if (externalValue < m_threshold)
				{
					m_statusEffect.SetWarningDisplay(m_warning);
					return defaultValue;
				}
				m_statusEffect.SendWarningMessage(m_warning);
				float num = m_statusEffect.CalculateThresholdMultiplierForStat(m_threshold);
				return m_calculationType switch
				{
					CalculationType.REGULAR => num * m_maxMultiplier, 
					CalculationType.INVERSE => 1f - num * m_maxMultiplier, 
					CalculationType.NEGATIVE => -1f * num * m_maxMultiplier, 
					CalculationType.PLUSONESHIFT => 1f + num * (m_maxMultiplier - 1f), 
					CalculationType.PERCENTAGE => Mathf.Clamp(num * m_maxMultiplier, 0f, 100f), 
					CalculationType.INVERSEPERCENTAGE => Mathf.Clamp(100f - num * (100f - m_maxMultiplier), 0f, 100f), 
					CalculationType.ONEZERO => Mathf.CeilToInt(num), 
					_ => m_maxMultiplier, 
				};
			}
		}

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(0)]
		public class WarningMessage
		{
			public bool m_display = false;

			public string m_message = "";

			public float m_lastMessageTime = 0f;

			public WarningMessage(string m_message)
			{
				this.m_message = m_message;
			}
		}

		public float m_statLoss = 0f;

		public float m_maxStatLoss = 100f;

		public float m_baseMaxStatLoss = 100f;

		public float m_statLossPerc = 0f;

		public float m_statChange = 0f;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(new byte[] { 2, 1 })]
		protected Sprite[] m_icons;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		protected Sprite m_iconNoSkillDrain;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		protected Sprite m_iconNewSpawn;

		protected float updateTimerState = 0f;

		protected float updateTimerStats = 0f;

		protected float updateTimerIcon = 0f;

		protected float updateTimerLogs = 0f;

		protected float countdownTimer = 300f;

		public readonly Dictionary<string, DamageModPair> m_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
				}
			}
		};

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		protected Player player;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		protected SE_PlayerStats pes;

		protected virtual string SENameKey => "$ea";

		protected virtual string IconName => "icon";

		protected virtual int IconCount => 0;

		protected virtual string DataKey => "EnvironmentalAwareness_";

		protected virtual string TooltipKey => "$ea";

		protected virtual bool DisplayPercentageEnabledConfigEntry => true;

		protected virtual bool DisplayWarningTextsConfigEntry => true;

		protected virtual string[] Statuses => new string[0];

		public override void Setup(Character character)
		{
			((SE_Stats)this).Setup(character);
			((StatusEffect)this).m_name = SENameKey;
			LoadIcons();
			((StatusEffect)this).m_icon = m_icons[0];
			SetupBaseFields();
			SetupTimerFields();
			SetupExtraFields();
			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);
				return;
			}
			SetupStatModifiers();
			Main.LogMessage("Status effect " + ((Object)this).name + " added to player.");
			LoadData();
			Recalculate();
		}

		public override void Stop()
		{
			((StatusEffect)this).Stop();
			SetupBaseFields();
			SetupTimerFields();
			SetupExtraFields();
			Main.LogMessage("Status effect " + ((Object)this).name + " removed from player.");
		}

		protected virtual void LoadIcons()
		{
			Sprite[] array = (Sprite[])(object)new Sprite[IconCount];
			for (int i = 0; i < IconCount; i++)
			{
				string text = IconName + (i + 1);
				array[i] = Main.GetInstance().Bundle.LoadAsset<Sprite>(text);
			}
			m_icons = array;
			m_iconNoSkillDrain = Main.GetInstance().Bundle.LoadAsset<Sprite>(IconName + "death");
			m_iconNewSpawn = Main.GetInstance().Bundle.LoadAsset<Sprite>(IconName + "newplayer");
		}

		public virtual void SetupBaseFields()
		{
			m_statLoss = 0f;
			m_statLossPerc = 0f;
			m_baseMaxStatLoss = 100f;
			m_maxStatLoss = 100f;
		}

		public virtual void SetupTimerFields()
		{
			((StatusEffect)this).m_ttl = 1f;
			updateTimerState = 0f;
			updateTimerStats = 0f;
			updateTimerIcon = 0f;
			updateTimerLogs = 0f;
			countdownTimer = ConfigManager.NewPlayerCooldown.Value;
		}

		protected virtual void SetupExtraFields()
		{
		}

		protected virtual void SetupStatModifiers()
		{
		}

		protected virtual void LoadData()
		{
			Main.LogMessage("Loading data for " + ((Object)this).name);
			if ((Object)(object)player == (Object)null)
			{
				Main.LogMessage("No player found. Cannot load data.");
				return;
			}
			if (!player.m_customData.TryGetValue(DataKey, out var value))
			{
				Main.LogMessage("No save data found for the player profile.");
				return;
			}
			if (string.IsNullOrEmpty(value))
			{
				Main.LogMessage("No save data found in entry " + DataKey);
				return;
			}
			Main.LogMessage("Loaded data: " + value);
			List<string> list = value.Split(new char[1] { ':' }).ToList();
			try
			{
				list[0].AssignAsFloat(out countdownTimer);
				list[1].AssignAsFloat(out m_statLoss);
				list[2].AssignAsFloat(out m_maxStatLoss);
				list[3].AssignAsFloat(out m_statLossPerc);
				LoadExtraFields(list);
			}
			catch (Exception ex)
			{
				Main.LogMessage("Could not parse data for " + DataKey + ". Cancelling load.");
				Main.LogMessage(ex.Message);
			}
			finally
			{
				player.m_customData.Remove(DataKey);
				Main.LogMessage("Loaded. Removed data key " + DataKey + " from player data.");
			}
		}

		public virtual void ClearSaveData()
		{
			Main.LogMessage("Clearing existing save data for " + ((Object)this).name);
			if ((Object)(object)player == (Object)null)
			{
				Main.LogMessage("No player found. Cannot load data.");
				return;
			}
			if (!player.m_customData.TryGetValue(DataKey, out var _))
			{
				Main.LogMessage("No save data found for the player profile - no need to clear.");
				return;
			}
			player.m_customData.Remove(DataKey);
			Main.LogMessage("Cleared save data key " + DataKey + " from player data.");
		}

		protected virtual void LoadExtraFields(List<string> list)
		{
		}

		public virtual void SaveData()
		{
			if (!ConfigManager.SavingEnabled.Value)
			{
				Main.LogMessage("Saving is not enabled. Skipping save data.");
				return;
			}
			Main.LogMessage("Saving data for " + ((Object)this).name);
			if ((Object)(object)player == (Object)null)
			{
				Main.LogMessage("No player found. Cannot save data.");
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendStat(countdownTimer);
			stringBuilder.AppendStat(m_statLoss);
			stringBuilder.AppendStat(m_maxStatLoss);
			stringBuilder.AppendStat(m_statLossPerc);
			SaveExtraFields(stringBuilder);
			string text = stringBuilder.ToString().TrimEnd(new char[1] { ',' });
			if (player.m_customData.TryGetValue(DataKey, out var _))
			{
				Main.LogMessage("Previous save data found. Replacing...");
				player.m_customData.Remove(DataKey);
			}
			player.m_customData.Insert(DataKey, text);
			Main.LogMessage("Saved data: " + text);
		}

		protected virtual void SaveExtraFields(StringBuilder sb)
		{
		}

		public override string GetTooltipString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (pes.PlayerNoSkillDrain)
			{
				stringBuilder.AppendFormat("{0}_immune \n", TooltipKey);
				return stringBuilder.ToString();
			}
			if (countdownTimer > 0f)
			{
				stringBuilder.AppendFormat("{0}_cooldown: {1}s. \n", TooltipKey, Mathf.Ceil(countdownTimer));
				return stringBuilder.ToString();
			}
			stringBuilder.Append(GetStatusString());
			GetPlayerHintStrings(stringBuilder);
			if (m_statChange > 0f)
			{
				GetStatLossHintStrings(stringBuilder);
			}
			else if (m_statChange < 0f && m_statLoss > 0.5f)
			{
				GetStatGainHintStrings(stringBuilder);
			}
			stringBuilder.Append(base.GetTooltipString());
			GetStatChangeStrings(stringBuilder);
			if (ConfigManager.ShowDebugValueInSE.Value)
			{
				stringBuilder.Append("<color=orange>Debug info</color> \n");
				stringBuilder.Append(((object)this).ToString());
			}
			return stringBuilder.ToString();
		}

		protected virtual void GetPlayerHintStrings(StringBuilder sb)
		{
		}

		protected virtual void GetStatLossHintStrings(StringBuilder sb)
		{
		}

		protected virtual void GetStatGainHintStrings(StringBuilder sb)
		{
		}

		protected virtual void GetStatChangeStrings(StringBuilder sb)
		{
		}

		protected virtual string GetStatusString()
		{
			if (Statuses == null || Statuses.Length == 0)
			{
				return "";
			}
			int num = Mathf.Clamp(Mathf.FloorToInt(m_statLoss / m_maxStatLoss * (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 (!DisplayPercentageEnabledConfigEntry)
			{
				return "";
			}
			int num = 100 - Mathf.FloorToInt(m_statLossPerc);
			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);
			m_statLossPerc = CalculateStatLossPercentage();
			if (countdownTimer <= 0f && !pes.PlayerNoSkillDrain)
			{
				UpdateRealtimeExternalStatChanges(dt);
				updateTimerState += dt;
				updateTimerStats += dt;
			}
			updateTimerIcon += dt;
			updateTimerLogs += dt;
			if (!((Object)(object)player == (Object)null))
			{
				if (updateTimerState >= 1f && countdownTimer <= 0f && !pes.PlayerNoSkillDrain)
				{
					UpdatePerSecondStateChanges();
					UpdateStatValue();
					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;
				}
			}
		}

		protected virtual void UpdatePerSecondStateChanges()
		{
		}

		protected virtual void UpdateRealtimeExternalStatChanges(float dt)
		{
		}

		protected virtual void UpdateStatValue()
		{
		}

		protected virtual void UpdateEffects()
		{
		}

		protected virtual void UpdateTutorial()
		{
		}

		public virtual void Recalculate()
		{
			Main.LogMessage("Recalculating stats for " + ((Object)this).name + " SE.");
			m_maxStatLoss = m_baseMaxStatLoss + CalculateAdditionalMaxStat();
		}

		protected virtual float CalculateAdditionalMaxStat()
		{
			return 0f;
		}

		protected virtual float CalculateStatLossPercentage()
		{
			return 100f * (m_statLoss / m_maxStatLoss);
		}

		protected virtual void ChangeStatLossByPercentage(float percentageChange)
		{
			float num = Mathf.Clamp(m_statLossPerc + percentageChange, 0f, 100f);
			m_statLoss = num / 100f * m_maxStatLoss;
			m_statLossPerc = num;
		}

		protected virtual float CalculateThresholdMultiplierForStat(float threshold)
		{
			return Mathf.Clamp((m_statLoss - threshold) / (m_maxStatLoss - threshold), 0f, 1f);
		}

		public override bool IsDone()
		{
			return false;
		}

		protected virtual void LogStatistics()
		{
		}

		protected virtual void ResetCycleStats()
		{
		}

		[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(2)]
		public virtual void SendWarningMessage(WarningMessage warning)
		{
			if (warning != null && warning.m_display && Time.time - warning.m_lastMessageTime > 5f)
			{
				SendPlayerMessage(warning.m_message);
				warning.m_display = false;
				warning.m_lastMessageTime = Time.time;
			}
		}

		[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(2)]
		public virtual void SetWarningDisplay(WarningMessage warning)
		{
			if (warning != null)
			{
				warning.m_display = true;
			}
		}

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

		protected void UpdateIcon()
		{
			if (pes.PlayerNoSkillDrain)
			{
				((StatusEffect)this).m_icon = m_iconNoSkillDrain;
				return;
			}
			if (countdownTimer > 0f)
			{
				((StatusEffect)this).m_icon = m_iconNewSpawn;
				return;
			}
			int num = Mathf.RoundToInt((float)m_icons.Length * (m_statLoss / m_maxStatLoss));
			if (num > m_icons.Length - 1)
			{
				num = m_icons.Length - 1;
			}
			((StatusEffect)this).m_icon = m_icons[num];
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendFormat("SENameKey: {0}\n", SENameKey);
			stringBuilder.AppendFormat("DataKey: {0}\n", DataKey);
			stringBuilder.AppendFormat("m_statLoss: {0}\n", m_statLoss);
			stringBuilder.AppendFormat("m_maxStatLoss: {0}\n", m_maxStatLoss);
			stringBuilder.AppendFormat("m_baseMaxStatLoss: {0}\n", m_baseMaxStatLoss);
			stringBuilder.AppendFormat("m_statLossPerc: {0}\n", m_statLossPerc);
			stringBuilder.AppendFormat("m_statChange: {0}\n", m_statChange);
			GetAdditionalDebugStrings(stringBuilder);
			return stringBuilder.ToString();
		}

		public virtual void GetAdditionalDebugStrings(StringBuilder sb)
		{
			sb.Append("<color=yellow>Extra Parameters</color>\n");
		}
	}
	[<f2242118-9e71-4a34-a1f5-d0f964310b0c>NullableContext(1)]
	[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(0)]
	public class SE_Vitality : SE_SurvivalBase
	{
		public float m_foodBurnMult = 1f;

		public float m_foodStatBurn = 1f;

		public float m_vulnerabilityFromDamage = 0f;

		public float m_vulnerabilitySkillResist = 0f;

		public float m_seasonMultiplier = 1f;

		public float m_armorReduction = 0f;

		public bool m_physicalWeaknessActive = false;

		public bool m_elementalWeaknessActive = false;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_healthPerTickModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_healthRegenModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_staminaMultModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_foodBurnModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_moveSpeedModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_physicalWeaknessModifier;

		[<b743f850-bec7-468a-9daa-3c17ad10c240>Nullable(2)]
		public StatModifier c_elementalWeaknessModifier;

		public WarningMessage c_warningHealth = new WarningMessage("$ea_vitality_warningmessage_health");

		public WarningMessage c_warningStamina = new WarningMessage("$ea_vitality_warningmessage_stamina");

		public WarningMessage c_warningFood = new WarningMessage("$ea_vitality_warningmessage_foodburn");

		public WarningMessage c_warningSpeed = new WarningMessage("$ea_vitality_warningmessage_movement");

		public WarningMessage c_warningPhysical = new WarningMessage("$ea_vitality_warningmessage_physical");

		public WarningMessage c_warningElemental = new WarningMessage("$ea_vitality_warningmessage_elemental");

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

		protected override string SENameKey => "$ea_se_vitality";

		protected override string IconName => "vitalityicon";

		protected override int IconCount => 10;

		protected override string DataKey => "EnvironmentalAwareness_" + Main.VitalitySEName;

		protected override string TooltipKey => "$ea_player_vulnerability";

		protected override bool DisplayPercentageEnabledConfigEntry => ConfigManager.DisplayVitalityPercentage.Value;

		protected override bool DisplayWarningTextsConfigEntry => ConfigManager.DisplayVitalityWarningTexts.Value;

		protected override 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" };

		protected override void SetupStatModifiers()
		{
			c_healthPerTickModifier = new StatModifier(this, c_warningHealth, StatModifier.CalculationType.NEGATIVE)
			{
				m_enabled = ConfigManager.VHealthDamageEnabled.Value,
				m_maxMultiplier = ConfigManager.VHealthMaxDamageOverTime.Value,
				m_threshold = ConfigManager.VHealthDamageMinStartThreshold.Value,
				m_defaultValue = 0f
			};
			c_healthRegenModifier = new StatModifier(this, null, StatModifier.CalculationType.INVERSE)
			{
				m_enabled = ConfigManager.VHealthDamageEnabled.Value,
				m_maxMultiplier = ConfigManager.VHealthMaxRegenReduction.Value,
				m_threshold = ConfigManager.VHealthDamageMinStartThreshold.Value,
				m_defaultValue = 1f
			};
			c_staminaMultModifier = new StatModifier(this, c_warningStamina, StatModifier.CalculationType.INVERSE)
			{
				m_enabled = ConfigManager.VStaminaRegenReductionEnabled.Value,
				m_maxMultiplier = ConfigManager.VStaminaRegenMaxReduction.Value,
				m_threshold = ConfigManager.VStaminaRegenReductionThreshold.Value,
				m_defaultValue = 1f
			};
			c_foodBurnModifier = new StatModifier(this, c_warningFood, StatModifier.CalculationType.PLUSONESHIFT)
			{
				m_enabled = ConfigManager.VFoodBurnRateEnabled.Value,
				m_maxMultiplier = ConfigManager.VFoodBurnMaxOverTime.Value,
				m_threshold = ConfigManager.VFoodBurnMinStartThreshold.Value,
				m_defaultValue = 1f
			};
			c_moveSpeedModifier = new StatModifier(this, c_warningSpeed, StatModifier.CalculationType.NEGATIVE)
			{
				m_enabled = ConfigManager.VMoveSpeedReductionEnabled.Value,
				m_maxMultiplier = ConfigManager.VMoveSpeedMaxReduction.Value,
				m_threshold = ConfigManager.VMoveSpeedMinStartThreshold.Value,
				m_defaultValue = 0f
			};
			c_physicalWeaknessModifier = new StatModifier(this, c_warningPhysical, StatModifier.CalculationType.ONEZERO)
			{
				m_enabled = ConfigManager.VPhysicalWeaknessEnabled.Value,
				m_maxMultiplier = 1f,
				m_threshold = ConfigManager.VPhysicalWeaknessThreshold.Value,
				m_defaultValue = 0f
			};
			c_elementalWeaknessModifier = new StatModifier(this, c_warningElemental, StatModifier.CalculationType.ONEZERO)
			{
				m_enabled = ConfigManager.VElementalWeaknessEnabled.Value,
				m_maxMultiplier = 1f,
				m_threshold = ConfigManager.VElementalWeaknessThreshold.Value,
				m_defaultValue = 0f
			};
		}

		protected override void SetupExtraFields()
		{
			((SE_Stats)this).m_tickInterval = 5f;
			((SE_Stats)this).m_healthPerTick = 0f;
			((SE_Stats)this).m_healthRegenMultiplier = 1f;
			((SE_Stats)this).m_staminaRegenMultiplier = 1f;
			m_foodBurnMult = 1f;
			((SE_Stats)this).m_mods = new List<DamageModPair>();
			m_vulnerabilityFromDamage = 0f;
			m_vulnerabilitySkillResist = 0f;
			m_seasonMultiplier = 1f;
			m_armorReduction = 0f;
		}

		protected override void LoadExtraFields(List<string> list)
		{
			list[4].AssignAsFloat(out m_foodBurnMult);
			list[5].AssignAsFloat(out m_foodStatBurn);
			list[6].AssignAsFloat(out m_vulnerabilityFromDamage);
			list[7].AssignAsFloat(out m_vulnerabilitySkillResist);
			list[8].AssignAsFloat(out m_seasonMultiplier);
			list[9].AssignAsFloat(out m_armorReduction);
			list[10].AssignAsBool(out c_warningHealth.m_display);
			list[11].AssignAsBool(out c_warningStamina.m_display);
			list[12].AssignAsBool(out c_warningFood.m_display);
			list[13].AssignAsBool(out c_warningSpeed.m_display);
			list[14].AssignAsBool(out c_warningPhysical.m_display);
			list[15].AssignAsBool(out c_warningElemental.m_display);
		}

		protected override void SaveExtraFields(StringBuilder sb)
		{
			sb.AppendStat(m_foodBurnMult);
			sb.AppendStat(m_foodStatBurn);
			sb.AppendStat(m_vulnerabilityFromDamage);
			sb.AppendStat(m_vulnerabilitySkillResist);
			sb.AppendStat(m_seasonMultiplier);
			sb.AppendStat(m_armorReduction);
			sb.AppendStat(c_warningHealth.m_display);
			sb.AppendStat(c_warningStamina.m_display);
			sb.AppendStat(c_warningFood.m_display);
			sb.AppendStat(c_warningSpeed.m_display);
			sb.AppendStat(c_warningPhysical.m_display);
			sb.AppendStat(c_warningElemental.m_display);
		}

		protected override void GetPlayerHintStrings(StringBuilder sb)
		{
			if (pes.VitalityMaxPercentage <= 99f)
			{
				sb.AppendFormat("$ea_player_vitality_capped \n", Mathf.RoundToInt(pes.VitalityMaxPercentage));
			}
			if (pes.PlayerHealingMead)
			{
				sb.Append("$ea_player_healing_mead \n");
			}
		}

		protected override void GetStatLossHintStrings(StringBuilder sb)
		{
			if (!pes.PlayerSheltered && (pes.EnvironmentCold || pes.EnvironmentFreezing))
			{
				sb.Append("$ea_player_coldfreezing_vitality \n");
			}
			if (pes.PlayerHungry)
			{
				sb.Append("$ea_player_hungry_vitality \n");
			}
			if (pes.PlayerInHarshBiome)
			{
				sb.Append("$ea_player_harshbiome_vitality \n");
			}
			if (pes.PlayerSheltered && !pes.PlayerNearFire && pes.EnvironmentFreezing)
			{
				sb.Append("$ea_player_too_cold_shelter_vitality \n");
			}
		}

		protected override void GetStatGainHintStrings(StringBuilder sb)
		{
			sb.Append("$ea_player_recovering_vitality \n");
		}

		protected override void GetStatChangeStrings(StringBuilder sb)
		{
			if (((SE_Stats)this).m_healthPerTick != 0f)
			{
				sb.AppendFormat("$se_health: <color=orange>{0}</color> \n", Mathf.Floor(((SE_Stats)this).m_healthPerTick).ToString("+0;-0"));
			}
			if (m_foodBurnMult >= 1.01f)
			{
				sb.AppendFormat("$ea_se_foodburn: <color=orange>{0}</color> \n", (Mathf.Round(m_foodBurnMult * 100f) / 100f).ToString());
			}
		}

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

		public override void Recalculate()
		{
			base.Recalculate();
			m_vulnerabilitySkillResist = CalculateResistanceFromSkill();
			m_seasonMultiplier = CalculateSeasonMultiplier();
			m_statChange = CalculateVulnerabilityChange();
			Main.LogMessage("Stat change: " + m_statChange);
		}

		protected override void UpdateStatValue()
		{
			m_statLoss = Mathf.Clamp(m_statLoss + m_statChange + m_vulnerabilityFromDamage, 0f, m_maxStatLoss);
			m_statLoss = Mathf.Max((100f - pes.VitalityMaxPercentage) * m_maxStatLoss / 100f, m_statLoss);
			m_vulnerabilityFromDamage = 0f;
		}

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

		private 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 = ConfigManage