Decompiled source of Fatigue v1.1.2

FatigueMod.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("FatigueMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.2.0")]
[assembly: AssemblyInformationalVersion("1.1.2")]
[assembly: AssemblyProduct("FatigueMod")]
[assembly: AssemblyTitle("FatigueMod")]
[assembly: AssemblyVersion("1.1.2.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FatigueMod
{
	[BepInPlugin("com.tambistudios.fatigue", "Fatigue", "1.1.1")]
	public class FatiguePlugin : BaseUnityPlugin
	{
		public const string MOD_GUID = "com.tambistudios.fatigue";

		public const string MOD_NAME = "Fatigue";

		public const string MOD_VERSION = "1.1.1";

		public static FatiguePlugin Instance;

		public static ManualLogSource Logger;

		public static ConfigEntry<bool> debugMode;

		public const float ENERGY_MAX = 6.5f;

		public const float CLIMBJUMP_ENERGY_COST = 1.5f;

		public const float CLIMBJUMP_WINDOW = 0.3f;

		public const float COST_CLIMB_UP = 1f;

		public const float COST_CLIMB_SIDE = 1.3f;

		public const float COST_CLIMB_DOWN = 0.5f;

		public const float COST_CLIMB_HANG = 0.1f;

		public const float GROUND_REST_DELAY = 1.5f;

		public const float ENERGY_REGEN_PER_SEC = 1f;

		public const float ENERGY_REGEN_AIR = 0.4f;

		public const float COST_ROPE_MOVE = 0.3f;

		public const float COST_ROPE_HANG = 0.1f;

		public const float COST_VINE_MOVE = 0.9f;

		public const float COST_VINE_HANG = 0.1f;

		public const float DROWSY_GAIN_ACTIVE = 0.05f;

		public const float DROWSY_GAIN_HANG = 0.025f;

		public const float BUGLE_RANGE = 30f;

		public const float BUGLE_DROWSY_REDUCTION = 0.05f;

		public const float BUGLE_DURATION = 2f;

		public const float CAMPFIRE_DROWSY_MULTIPLIER = 4f;

		public const float VERTICAL_SPEED_THRESHOLD = 0.5f;

		public const float HANG_SPEED_THRESHOLD = 0.3f;

		internal static readonly Color EnergyBarColor = new Color(0.25f, 0.75f, 0.25f, 1f);

		internal static readonly Color EnergyBarColorLight = new Color(0.55f, 0.98f, 0.55f, 1f);

		internal static readonly Color EnergyBarBgColor = new Color(0.04f, 0.18f, 0.04f, 0.85f);

		private RectTransform _fillRect;

		private Image _fillImage;

		private StaminaBar _staminaBarRef;

		private FieldInfo _fullBarField;

		private bool _barCreated;

		private float _prevEnergy = -1f;

		private float _pulseTimer;

		private float _displayedWidth = -1f;

		private void Awake()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			debugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebugKeys", false, "Enables on-screen debug HUD showing energy budget and movement state.");
			try
			{
				Harmony val = new Harmony("com.tambistudios.fatigue");
				val.PatchAll();
				Type type = null;
				Type[] types = typeof(Character).Assembly.GetTypes();
				foreach (Type type2 in types)
				{
					if (type2.Name == "BugleSFX")
					{
						type = type2;
						break;
					}
				}
				if (type != null)
				{
					MethodInfo methodInfo = AccessTools.Method(type, "RPC_StartToot", (Type[])null, (Type[])null);
					MethodInfo methodInfo2 = AccessTools.Method(type, "RPC_EndToot", (Type[])null, (Type[])null);
					if (methodInfo != null)
					{
						val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Bugle_Patch), "OnStart", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Logger.LogInfo((object)"Bugle: patched RPC_StartToot");
					}
					if (methodInfo2 != null)
					{
						val.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(Bugle_Patch), "OnEnd", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Logger.LogInfo((object)"Bugle: patched RPC_EndToot");
					}
					if (methodInfo == null && methodInfo2 == null)
					{
						Logger.LogWarning((object)"BugleSFX found but no matching methods.");
					}
				}
				else
				{
					Logger.LogWarning((object)"BugleSFX class not found — bugle relief disabled.");
				}
				Logger.LogInfo((object)"[Fatigue 1.1.1] Loaded.");
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"Harmony patch failed: {arg}");
			}
		}

		public static float GetEtcDamageMultiplier()
		{
			try
			{
				return Ascents.etcDamageMultiplier;
			}
			catch
			{
				return 1f;
			}
		}

		public static bool IsFatigueDisabled()
		{
			return GetEtcDamageMultiplier() <= 0.001f;
		}

		public static float GetCostMultiplier()
		{
			float etcDamageMultiplier = GetEtcDamageMultiplier();
			if (etcDamageMultiplier <= 0.001f)
			{
				return 0f;
			}
			if (etcDamageMultiplier <= 0.6f)
			{
				return 1f;
			}
			if (etcDamageMultiplier <= 1.5f)
			{
				return 1.5f;
			}
			return 2f;
		}

		private void Update()
		{
			if (_barCreated && (Object)(object)_fillRect == (Object)null)
			{
				_barCreated = false;
				_staminaBarRef = null;
				_displayedWidth = -1f;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter != (Object)null && (Object)(object)((Component)localCharacter).GetComponent<FatigueTracker>() == (Object)null)
			{
				((Component)localCharacter).gameObject.AddComponent<FatigueTracker>();
				Logger.LogInfo((object)"FatigueTracker attached (fallback).");
			}
			if (!_barCreated && (Object)(object)localCharacter != (Object)null)
			{
				TryCreateEnergyBar();
			}
		}

		private void LateUpdate()
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			if (!_barCreated || (Object)(object)_fillRect == (Object)null || (Object)(object)_staminaBarRef == (Object)null)
			{
				return;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null)
			{
				return;
			}
			FatigueTracker component = ((Component)localCharacter).GetComponent<FatigueTracker>();
			if (!((Object)(object)component == (Object)null))
			{
				float energy = component.energy;
				float num = energy / 6.5f;
				object? obj = _fullBarField?.GetValue(_staminaBarRef);
				RectTransform val = (RectTransform)((obj is RectTransform) ? obj : null);
				float num2 = (((Object)(object)val != (Object)null) ? (val.sizeDelta.x * 0.9f) : 200f) * num;
				if (_displayedWidth < 0f)
				{
					_displayedWidth = num2;
				}
				_displayedWidth = Mathf.Lerp(_displayedWidth, num2, Time.deltaTime * 5f);
				Vector2 sizeDelta = _fillRect.sizeDelta;
				sizeDelta.x = _displayedWidth;
				_fillRect.sizeDelta = sizeDelta;
				bool num3 = _prevEnergy >= 0f && energy < _prevEnergy - 0.001f;
				_prevEnergy = energy;
				if (num3)
				{
					_pulseTimer += Time.deltaTime;
					float num4 = (Mathf.Sin(_pulseTimer * 9f) + 1f) * 0.5f;
					((Graphic)_fillImage).color = Color.Lerp(EnergyBarColor, EnergyBarColorLight, num4 * 0.45f);
				}
				else
				{
					_pulseTimer = 0f;
					((Graphic)_fillImage).color = EnergyBarColor;
				}
			}
		}

		private void TryCreateEnergyBar()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				StaminaBar val = Object.FindObjectOfType<StaminaBar>();
				if (!((Object)(object)val == (Object)null))
				{
					_fullBarField = AccessTools.Field(typeof(StaminaBar), "fullBar");
					object? obj = _fullBarField?.GetValue(val);
					RectTransform val2 = (RectTransform)((obj is RectTransform) ? obj : null);
					if ((Object)(object)val2 == (Object)null)
					{
						Logger.LogWarning((object)"StaminaBar.fullBar not found");
						return;
					}
					Transform parent = ((Component)val2).transform.parent;
					float x = val2.sizeDelta.x;
					float num = x * 0.9f;
					float num2 = val2.sizeDelta.y / 3.23f;
					float num3 = val2.anchoredPosition.x - val2.pivot.x * x;
					float num4 = val2.anchoredPosition.y + val2.sizeDelta.y * 0.5f + num2 * 0.5f + 3.5f;
					Sprite sprite = MakeRoundedSprite(12, 4);
					Sprite sprite2 = MakeRingSprite(28, 12, 4);
					GameObject val3 = new GameObject("FatigueEnergyBg");
					val3.transform.SetParent(parent, false);
					RectTransform obj2 = val3.AddComponent<RectTransform>();
					obj2.anchorMin = val2.anchorMin;
					obj2.anchorMax = val2.anchorMax;
					obj2.pivot = new Vector2(0f, 0.5f);
					obj2.sizeDelta = new Vector2(num, num2);
					obj2.anchoredPosition = new Vector2(num3, num4);
					Image obj3 = val3.AddComponent<Image>();
					((Graphic)obj3).color = EnergyBarBgColor;
					obj3.sprite = sprite;
					obj3.type = (Type)1;
					GameObject val4 = new GameObject("FatigueEnergyFill");
					val4.transform.SetParent(parent, false);
					_fillRect = val4.AddComponent<RectTransform>();
					_fillRect.anchorMin = val2.anchorMin;
					_fillRect.anchorMax = val2.anchorMax;
					_fillRect.pivot = new Vector2(0f, 0.5f);
					_fillRect.sizeDelta = new Vector2(num, num2);
					_fillRect.anchoredPosition = new Vector2(num3, num4);
					_fillImage = val4.AddComponent<Image>();
					((Graphic)_fillImage).color = EnergyBarColor;
					_fillImage.sprite = sprite;
					_fillImage.type = (Type)1;
					float num5 = num2 * 0.26f;
					GameObject val5 = new GameObject("FatigueEnergyOutline");
					val5.transform.SetParent(parent, false);
					RectTransform obj4 = val5.AddComponent<RectTransform>();
					obj4.anchorMin = val2.anchorMin;
					obj4.anchorMax = val2.anchorMax;
					obj4.pivot = new Vector2(0f, 0.5f);
					obj4.sizeDelta = new Vector2(num + num5 * 2f, num2 + num5 * 2f);
					obj4.anchoredPosition = new Vector2(num3 - num5, num4);
					Image obj5 = val5.AddComponent<Image>();
					((Graphic)obj5).color = new Color(1f, 1f, 1f, 0.85f);
					obj5.sprite = sprite2;
					obj5.type = (Type)1;
					_staminaBarRef = val;
					_barCreated = true;
					Logger.LogInfo((object)$"FatigueEnergyBar created. pos=({num3:F0},{num4:F0})");
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Energy bar setup failed: " + ex.Message));
			}
		}

		private static Sprite MakeRingSprite(int size, int radius, int ring)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			Color[] array = (Color[])(object)new Color[size * size];
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					bool flag = InRoundedRect(j, i, size, size, radius);
					bool flag2 = j >= ring && i >= ring && j < size - ring && i < size - ring && InRoundedRect(j - ring, i - ring, size - ring * 2, size - ring * 2, Math.Max(0, radius - ring));
					array[i * size + j] = ((flag && !flag2) ? Color.white : Color.clear);
				}
			}
			val.SetPixels(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4((float)radius, (float)radius, (float)radius, (float)radius));
		}

		private static Sprite MakeRoundedSprite(int size, int radius)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			Color[] array = (Color[])(object)new Color[size * size];
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					array[i * size + j] = (InRoundedRect(j, i, size, size, radius) ? Color.white : Color.clear);
				}
			}
			val.SetPixels(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4((float)radius, (float)radius, (float)radius, (float)radius));
		}

		private static bool InRoundedRect(int x, int y, int w, int h, int r)
		{
			if (x >= r && x <= w - 1 - r)
			{
				return true;
			}
			if (y >= r && y <= h - 1 - r)
			{
				return true;
			}
			int num = ((x < r) ? r : (w - 1 - r));
			int num2 = ((y < r) ? r : (h - 1 - r));
			float num3 = x - num;
			float num4 = y - num2;
			return num3 * num3 + num4 * num4 <= (float)r * (float)r;
		}

		private void OnGUI()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			if (!debugMode.Value)
			{
				return;
			}
			Character localCharacter = Character.localCharacter;
			if (!((Object)(object)localCharacter == (Object)null))
			{
				FatigueTracker component = ((Component)localCharacter).GetComponent<FatigueTracker>();
				if (!((Object)(object)component == (Object)null))
				{
					GUIStyle val = new GUIStyle();
					val.fontSize = 18;
					val.normal.textColor = Color.white;
					float etcDamageMultiplier = GetEtcDamageMultiplier();
					float costMultiplier = GetCostMultiplier();
					string text = (IsFatigueDisabled() ? "DISABLED" : $"x{costMultiplier:F1}");
					float currentStatus = localCharacter.refs.afflictions.GetCurrentStatus((STATUSTYPE)6);
					float lastVerticalVelocity = component.lastVerticalVelocity;
					float lastSpeed = component.lastSpeed;
					GUI.Label(new Rect(20f, 200f, 700f, 30f), $"Energy: {component.energy:F2}/{6.5f:F0}   State: {component.lastState}   etcMult: {etcDamageMultiplier:F2} ({text})", val);
					GUI.Label(new Rect(20f, 222f, 700f, 30f), $"Cost: {component.lastCostPerSec:F2}/sec   Vy: {lastVerticalVelocity:F2}   |V|: {lastSpeed:F2}", val);
					GUI.Label(new Rect(20f, 244f, 700f, 30f), $"Climb: {component.isClimbing}   Rope: {component.isRopeClimbing}   Vine: {component.isVineClimbing}   Ground: {component.isGrounded} ({component.groundTimer:F1}s)   sinceClimbJump: {component.sinceClimbJump:F2}", val);
					GUI.Label(new Rect(20f, 266f, 700f, 30f), string.Format("Drowsy: {0:F3}   Hang: {1}   Campfire: {2}   Bugle: {3}", currentStatus, component.lastIsHang, component.nearCampfire ? "YES (x4)" : "no", (component.bugledUntil > Time.time) ? $"{component.bugledUntil - Time.time:F1}s" : "no"), val);
				}
			}
		}
	}
	public class FatigueTracker : MonoBehaviour
	{
		public Character character;

		public float energy = 6.5f;

		public string lastState = "idle";

		public float lastCostPerSec;

		public float lastVerticalVelocity;

		public float lastSpeed;

		public bool isGrounded;

		public bool isClimbing;

		public bool isRopeClimbing;

		public bool isVineClimbing;

		public float sinceClimbJump = 999f;

		public bool nearCampfire;

		public bool lastIsHang;

		public float bugledUntil = -1f;

		public float groundTimer;

		private float _lastProcessedClimbJump = -1f;

		private Rigidbody _cachedRb;

		private static FieldInfo _isGroundedField;

		private static FieldInfo _isClimbingField;

		private static FieldInfo _isRopeClimbingField;

		private static FieldInfo _isVineClimbingField;

		private static FieldInfo _sinceClimbJumpField;

		private static FieldInfo _drowsyReductionPerSecondField;

		private static bool _fieldsSearched;

		private Rigidbody GetRb()
		{
			if ((Object)(object)_cachedRb != (Object)null)
			{
				return _cachedRb;
			}
			if ((Object)(object)character == (Object)null)
			{
				return null;
			}
			_cachedRb = ((Component)character).GetComponentInChildren<Rigidbody>();
			return _cachedRb;
		}

		private static void EnsureFields(Character c)
		{
			if (_fieldsSearched)
			{
				return;
			}
			_fieldsSearched = true;
			if (!((Object)(object)c == (Object)null) && !((Object)(object)c.data == (Object)null))
			{
				Type type = ((object)c.data).GetType();
				BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public;
				_isGroundedField = type.GetField("isGrounded", bindingAttr);
				_isClimbingField = type.GetField("isClimbing", bindingAttr);
				_isRopeClimbingField = type.GetField("isRopeClimbing", bindingAttr);
				_isVineClimbingField = type.GetField("isVineClimbing", bindingAttr);
				_sinceClimbJumpField = type.GetField("sinceClimbJump", bindingAttr);
				if (c.refs != null && (Object)(object)c.refs.afflictions != (Object)null)
				{
					Type type2 = ((object)c.refs.afflictions).GetType();
					_drowsyReductionPerSecondField = type2.GetField("drowsyReductionPerSecond", bindingAttr) ?? type2.GetField("drowsyReductionPerSecond", BindingFlags.Instance | BindingFlags.NonPublic);
				}
				FatiguePlugin.Logger.LogInfo((object)($"Fields: grounded={_isGroundedField != null} climb={_isClimbingField != null} " + $"rope={_isRopeClimbingField != null} vine={_isVineClimbingField != null} " + $"sinceClimbJump={_sinceClimbJumpField != null} " + $"drowsyReduction={_drowsyReductionPerSecondField != null}"));
			}
		}

		private static bool GetBool(FieldInfo f, object obj)
		{
			if (f == null || obj == null)
			{
				return false;
			}
			try
			{
				return (bool)f.GetValue(obj);
			}
			catch
			{
				return false;
			}
		}

		private static float GetFloat(FieldInfo f, object obj, float fallback = 0f)
		{
			if (f == null || obj == null)
			{
				return fallback;
			}
			try
			{
				return (float)f.GetValue(obj);
			}
			catch
			{
				return fallback;
			}
		}

		private void Awake()
		{
			character = ((Component)this).GetComponent<Character>();
		}

		private void Update()
		{
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || !character.IsLocal || (Object)(object)character.data == (Object)null)
			{
				return;
			}
			EnsureFields(character);
			isGrounded = GetBool(_isGroundedField, character.data);
			isClimbing = GetBool(_isClimbingField, character.data);
			isRopeClimbing = GetBool(_isRopeClimbingField, character.data);
			isVineClimbing = GetBool(_isVineClimbingField, character.data);
			sinceClimbJump = GetFloat(_sinceClimbJumpField, character.data, 999f);
			nearCampfire = false;
			if (character.refs != null && (Object)(object)character.refs.afflictions != (Object)null)
			{
				try
				{
					nearCampfire = !character.refs.afflictions.canGetHungry;
				}
				catch
				{
					nearCampfire = false;
				}
			}
			if (nearCampfire && character.refs != null && (Object)(object)character.refs.afflictions != (Object)null)
			{
				float num = GetFloat(_drowsyReductionPerSecondField, character.refs.afflictions, 0.01f) * 3f;
				if (num > 0f && character.refs.afflictions.GetCurrentStatus((STATUSTYPE)6) > 0f)
				{
					character.refs.afflictions.SubtractStatus((STATUSTYPE)6, num * Time.deltaTime, false, false);
				}
			}
			if (Time.time < bugledUntil && character.refs != null && (Object)(object)character.refs.afflictions != (Object)null && character.refs.afflictions.GetCurrentStatus((STATUSTYPE)6) > 0f)
			{
				character.refs.afflictions.SubtractStatus((STATUSTYPE)6, 0.05f * Time.deltaTime, false, false);
			}
			Rigidbody rb = GetRb();
			if ((Object)(object)rb != (Object)null)
			{
				lastVerticalVelocity = rb.linearVelocity.y;
				Vector3 linearVelocity = rb.linearVelocity;
				lastSpeed = ((Vector3)(ref linearVelocity)).magnitude;
			}
			if (FatiguePlugin.IsFatigueDisabled())
			{
				lastState = "disabled";
				lastCostPerSec = 0f;
				energy = 6.5f;
				return;
			}
			if (isGrounded)
			{
				groundTimer += Time.deltaTime;
				lastCostPerSec = 0f;
				if (groundTimer >= 1.5f)
				{
					energy = Mathf.Min(6.5f, energy + 1f * Time.deltaTime);
				}
				lastState = ((energy >= 6.499f) ? "ground" : $"resting ({groundTimer:F1}s)");
				return;
			}
			groundTimer = 0f;
			float num2 = (lastCostPerSec = CalculateCost());
			if (num2 > 0f)
			{
				float costMultiplier = FatiguePlugin.GetCostMultiplier();
				energy = Mathf.Max(0f, energy - num2 * costMultiplier * Time.deltaTime);
			}
			if (isClimbing && sinceClimbJump < 0.3f)
			{
				if (_lastProcessedClimbJump < 0f || sinceClimbJump < _lastProcessedClimbJump)
				{
					energy = Mathf.Max(0f, energy - 1.5f);
					lastState = "CLIMBJUMP!";
					FatiguePlugin.Logger.LogInfo((object)$"ClimbJump detected: -{1.5f} energy");
				}
				_lastProcessedClimbJump = sinceClimbJump;
			}
			else
			{
				_lastProcessedClimbJump = -1f;
			}
			if (energy <= 0.001f)
			{
				float num3 = (lastIsHang ? 0.025f : 0.05f) * Time.deltaTime;
				if (num3 > 0f)
				{
					character.refs.afflictions.AddStatus((STATUSTYPE)6, num3, false, true, true);
				}
			}
		}

		private float CalculateCost()
		{
			if (isClimbing)
			{
				if (lastSpeed < 0.3f)
				{
					lastIsHang = true;
					lastState = "climb-hang";
					return 0.1f;
				}
				if (lastVerticalVelocity > 0.5f)
				{
					lastIsHang = false;
					lastState = "climb-up";
					return 1f;
				}
				if (lastVerticalVelocity < -0.5f)
				{
					lastIsHang = false;
					lastState = "climb-down";
					return 0.5f;
				}
				lastIsHang = false;
				lastState = "climb-side";
				return 1.3f;
			}
			if (isRopeClimbing)
			{
				if (lastSpeed < 0.3f)
				{
					lastIsHang = true;
					lastState = "rope-hang";
					return 0.1f;
				}
				lastIsHang = false;
				lastState = "rope-move";
				return 0.3f;
			}
			if (isVineClimbing)
			{
				if (lastSpeed < 0.3f)
				{
					lastIsHang = true;
					lastState = "vine-hang";
					return 0.1f;
				}
				lastIsHang = false;
				lastState = "vine-move";
				return 0.9f;
			}
			lastIsHang = false;
			lastState = "air";
			energy = Mathf.Min(6.5f, energy + 0.4f * Time.deltaTime);
			return 0f;
		}
	}
	[HarmonyPatch(typeof(Character), "Awake")]
	internal static class Character_Awake_Patch
	{
		[HarmonyPostfix]
		private static void Postfix(Character __instance)
		{
			if ((Object)(object)((Component)__instance).GetComponent<FatigueTracker>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<FatigueTracker>();
			}
		}
	}
	internal static class Bugle_Patch
	{
		private static Vector3 GetBuglePos(Component __instance)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				FieldInfo field = ((object)__instance).GetType().GetField("item", BindingFlags.Instance | BindingFlags.NonPublic);
				if (field != null)
				{
					object? value = field.GetValue(__instance);
					Item val = (Item)((value is Item) ? value : null);
					if ((Object)(object)((val != null) ? val.holderCharacter : null) != (Object)null)
					{
						return ((Component)val.holderCharacter).transform.position;
					}
				}
			}
			catch
			{
			}
			Character componentInParent = __instance.GetComponentInParent<Character>();
			if (!((Object)(object)componentInParent != (Object)null))
			{
				return __instance.transform.position;
			}
			return ((Component)componentInParent).transform.position;
		}

		public static void OnStart(Component __instance)
		{
			//IL_0017: 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)
			try
			{
				Character localCharacter = Character.localCharacter;
				if (!((Object)(object)localCharacter == (Object)null) && !(Vector3.Distance(((Component)localCharacter).transform.position, GetBuglePos(__instance)) > 30f))
				{
					FatigueTracker component = ((Component)localCharacter).GetComponent<FatigueTracker>();
					if (!((Object)(object)component == (Object)null))
					{
						component.bugledUntil = Time.time + 60f;
					}
				}
			}
			catch
			{
			}
		}

		public static void OnEnd(Component __instance)
		{
			try
			{
				Character localCharacter = Character.localCharacter;
				if (!((Object)(object)localCharacter == (Object)null))
				{
					FatigueTracker component = ((Component)localCharacter).GetComponent<FatigueTracker>();
					if ((Object)(object)component != (Object)null)
					{
						component.bugledUntil = -1f;
					}
				}
			}
			catch
			{
			}
		}
	}
}