Decompiled source of ClassModF v0.0.7

ClassMod-F.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using ClassModF;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak.Afflictions;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyCompany("ClassMod-F")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("ClassMod-F")]
[assembly: AssemblyTitle("ClassMod-F")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[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;
		}
	}
}
public enum PlayerClass
{
	Normal,
	Scout,
	Herbalist,
	Forager,
	Ranger,
	Tinkerer
}
public static class ClassManager
{
	public static Dictionary<int, float> CachedAfflictionMultipliers = new Dictionary<int, float>();

	public static PlayerClass CurrentClass { get; private set; } = PlayerClass.Normal;


	public static void Update()
	{
		if (Input.GetKeyDown((KeyCode)276))
		{
			SetClass(PreviousClass(CurrentClass));
		}
		else if (Input.GetKeyDown((KeyCode)275))
		{
			SetClass(NextClass(CurrentClass));
		}
	}

	public static void SetClass(PlayerClass newClass)
	{
		CurrentClass = newClass;
		CachedAfflictionMultipliers = ClassModifiers.GetAllAfflictionMultipliers(CurrentClass);
		ClassAbilities.AssignAbility(newClass);
	}

	private static PlayerClass PreviousClass(PlayerClass cls)
	{
		int num = (int)(cls - 1);
		if (num < 0)
		{
			num = Enum.GetValues(typeof(PlayerClass)).Length - 1;
		}
		return (PlayerClass)num;
	}

	private static PlayerClass NextClass(PlayerClass cls)
	{
		int num = (int)(cls + 1);
		if (num >= Enum.GetValues(typeof(PlayerClass)).Length)
		{
			num = 0;
		}
		return (PlayerClass)num;
	}
}
[HarmonyPatch]
public static class ClassPatches
{
	[HarmonyPatch(typeof(Character), "UseStamina", new Type[]
	{
		typeof(float),
		typeof(bool)
	})]
	[HarmonyPrefix]
	private static void UseStamina_Prefix(ref float __0, bool __1)
	{
		try
		{
			float staminaMultiplier = ClassModifiers.GetStaminaMultiplier(ClassManager.CurrentClass);
			__0 *= staminaMultiplier;
		}
		catch (Exception)
		{
		}
	}

	[HarmonyPatch(typeof(CharacterAfflictions), "UpdateWeight")]
	[HarmonyPostfix]
	private static void UpdateWeight_Postfix(CharacterAfflictions __instance)
	{
		try
		{
			float currentStatus = __instance.GetCurrentStatus((STATUSTYPE)7);
			float weightMultiplier = ClassModifiers.GetWeightMultiplier(ClassManager.CurrentClass);
			float num = currentStatus * weightMultiplier;
			__instance.SetStatus((STATUSTYPE)7, num, true);
		}
		catch (Exception)
		{
		}
	}
}
public interface IAbilityWithCooldown
{
	void ResetCooldown();
}
public class CooldownUI
{
	private static readonly Dictionary<string, CooldownUI> _instances = new Dictionary<string, CooldownUI>();

	private readonly string _name;

	private GameObject _root;

	private Image _circle;

	private TextMeshProUGUI _text;

	private Vector2 _targetPos;

	private float _cooldownDur;

	private float _cooldownT;

	private bool _active;

	public static CooldownUI Get(string name, Vector2 anchoredPosition)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		if (_instances.TryGetValue(name, out var value))
		{
			value._targetPos = anchoredPosition;
			value.ApplyAnchors();
			return value;
		}
		CooldownUI cooldownUI = new CooldownUI(name, anchoredPosition);
		_instances[name] = cooldownUI;
		return cooldownUI;
	}

	private CooldownUI(string name, Vector2 anchoredPosition)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		_name = name;
		_targetPos = anchoredPosition;
		CreateUI();
		SetReadyVisuals();
	}

	private static GameObject EnsureCanvasRoot()
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = GameObject.Find("ClassModF_CooldownRoot");
		if ((Object)(object)val != (Object)null)
		{
			return val;
		}
		val = new GameObject("ClassModF_CooldownRoot");
		Object.DontDestroyOnLoad((Object)(object)val);
		Canvas val2 = val.AddComponent<Canvas>();
		val2.renderMode = (RenderMode)0;
		val2.sortingOrder = 5000;
		CanvasScaler val3 = val.AddComponent<CanvasScaler>();
		val3.uiScaleMode = (ScaleMode)0;
		val3.referenceResolution = new Vector2(1920f, 1080f);
		val.AddComponent<GraphicRaycaster>();
		return val;
	}

	private void CreateUI()
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Expected O, but got Unknown
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		_root = EnsureCanvasRoot();
		GameObject val = new GameObject(_name + "_Circle");
		val.transform.SetParent(_root.transform, false);
		_circle = val.AddComponent<Image>();
		UI_UseItemProgress val2 = Object.FindFirstObjectByType<UI_UseItemProgress>();
		if ((Object)(object)Object.FindFirstObjectByType<UI_UseItemProgress>() != (Object)null && (Object)(object)Object.FindFirstObjectByType<UI_UseItemProgress>().fill != (Object)null)
		{
			_circle.sprite = val2.fill.sprite;
		}
		_circle.type = (Type)3;
		_circle.fillMethod = (FillMethod)4;
		_circle.fillOrigin = 2;
		_circle.fillClockwise = false;
		_circle.fillClockwise = false;
		_circle.fillAmount = 0f;
		((Graphic)_circle).color = new Color(0.2f, 1f, 0.2f, 0.9f);
		((Behaviour)_circle).enabled = true;
		ApplyAnchors();
		GameObject val3 = new GameObject(_name + "_Text");
		val3.transform.SetParent(((Component)_circle).transform, false);
		_text = val3.AddComponent<TextMeshProUGUI>();
		GameObject val4 = GameObject.Find("GAME/GUIManager");
		GUIManager val5 = (((Object)(object)val4 != (Object)null) ? val4.GetComponent<GUIManager>() : null);
		if ((Object)(object)val5 != (Object)null && (Object)(object)val5.heroDayText != (Object)null)
		{
			((TMP_Text)_text).font = ((TMP_Text)val5.heroDayText).font;
		}
		((TMP_Text)_text).alignment = (TextAlignmentOptions)514;
		((Graphic)_text).color = Color.white;
		((TMP_Text)_text).fontSize = 18f;
		RectTransform rectTransform = ((TMP_Text)_text).rectTransform;
		rectTransform.anchorMin = Vector2.zero;
		rectTransform.anchorMax = Vector2.one;
		rectTransform.offsetMin = Vector2.zero;
		rectTransform.offsetMax = Vector2.zero;
	}

	private void ApplyAnchors()
	{
		//IL_0029: 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_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_circle != (Object)null)
		{
			RectTransform rectTransform = ((Graphic)_circle).rectTransform;
			rectTransform.anchorMin = new Vector2(1f, 0f);
			rectTransform.anchorMax = new Vector2(1f, 0f);
			rectTransform.pivot = new Vector2(1f, 0f);
			rectTransform.anchoredPosition = _targetPos;
			rectTransform.sizeDelta = new Vector2(75f, 75f);
		}
	}

	private void SetReadyVisuals()
	{
		if ((Object)(object)_circle != (Object)null && (Object)(object)_text != (Object)null)
		{
			_circle.fillAmount = 1f;
			((TMP_Text)_text).text = "Ready";
		}
	}

	private void SetTickVisuals()
	{
		if ((Object)(object)_circle != (Object)null && (Object)(object)_text != (Object)null)
		{
			float fillAmount = ((_cooldownDur <= 0f) ? 0f : Mathf.Clamp01(1f - _cooldownT / _cooldownDur));
			_circle.fillAmount = fillAmount;
			int num = Mathf.FloorToInt(_cooldownT / 60f);
			int num2 = Mathf.FloorToInt(_cooldownT % 60f);
			((TMP_Text)_text).text = $"{num:00}:{num2:00}";
		}
	}

	public void StartCooldown(float durationSeconds)
	{
		_cooldownDur = Mathf.Max(0f, durationSeconds);
		_cooldownT = _cooldownDur;
		_active = _cooldownDur > 0f;
		if (_active)
		{
			SetTickVisuals();
		}
		else
		{
			SetReadyVisuals();
		}
		Show();
	}

	public void Update()
	{
		if (_active)
		{
			_cooldownT -= Time.deltaTime;
			if (_cooldownT <= 0f)
			{
				_cooldownT = 0f;
				_active = false;
				SetReadyVisuals();
			}
			else
			{
				SetTickVisuals();
			}
		}
	}

	public void Show()
	{
		if ((Object)(object)_circle != (Object)null)
		{
			((Component)_circle).gameObject.SetActive(true);
		}
		if ((Object)(object)_text != (Object)null)
		{
			((Component)_text).gameObject.SetActive(true);
		}
	}

	public void Hide()
	{
		if ((Object)(object)_circle != (Object)null)
		{
			((Component)_circle).gameObject.SetActive(false);
		}
		if ((Object)(object)_text != (Object)null)
		{
			((Component)_text).gameObject.SetActive(false);
		}
	}

	public static void Remove(string name)
	{
		if (_instances.TryGetValue(name, out var value) && (Object)(object)value._circle != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)value._circle).gameObject);
		}
	}
}
public class RestrictionPopup : MonoBehaviour
{
	private static RestrictionPopup? instance;

	private string message = "";

	private float showUntil;

	private void Awake()
	{
		instance = this;
	}

	private void OnGUI()
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: 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_0045: Expected O, but got Unknown
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		if (Time.time < showUntil && !string.IsNullOrEmpty(message))
		{
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)4,
				fontSize = 20
			};
			val.normal.textColor = Color.black;
			GUIStyle val2 = val;
			float num = 400f;
			float num2 = 30f;
			GUI.Label(new Rect(((float)Screen.width - num) / 2f, (float)Screen.height / 2f - 100f, num, num2), message, val2);
		}
	}

	public static void ShowMessage(string msg, float duration = 1f)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		if ((Object)(object)instance == (Object)null)
		{
			GameObject val = new GameObject("RestrictionPopup");
			instance = val.AddComponent<RestrictionPopup>();
			Object.DontDestroyOnLoad((Object)(object)val);
		}
		instance.message = msg;
		instance.showUntil = Time.time + duration;
	}
}
namespace ClassModF
{
	[BepInPlugin("com.classmod.f", "ClassMod-F", "1.0.0")]
	public class ClassModF : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <ResetCooldownsDelayed>d__3 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Scene scene;

			public ClassModF <>4__this;

			private float <timeout>5__1;

			private IEnumerator<IAbilityWithCooldown> <>s__2;

			private IAbilityWithCooldown <ability>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ResetCooldownsDelayed>d__3(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>s__2 = null;
				<ability>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<timeout>5__1 = 5f;
					break;
				case 3:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)Character.localCharacter == (Object)null && <timeout>5__1 > 0f)
				{
					<timeout>5__1 -= Time.unscaledDeltaTime;
					<>2__current = null;
					<>1__state = 3;
					return true;
				}
				<>s__2 = Object.FindObjectsByType<MonoBehaviour>((FindObjectsSortMode)0).OfType<IAbilityWithCooldown>().GetEnumerator();
				try
				{
					while (<>s__2.MoveNext())
					{
						<ability>5__3 = <>s__2.Current;
						<ability>5__3.ResetCooldown();
						<ability>5__3 = null;
					}
				}
				finally
				{
					if (<>s__2 != null)
					{
						<>s__2.Dispose();
					}
				}
				<>s__2 = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <SpawnStartingItemDelayed>d__4 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Scene scene;

			public ClassModF <>4__this;

			private float <timeout>5__1;

			private string <itemPrefab>5__2;

			private Item <item>5__3;

			private Exception <ex>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SpawnStartingItemDelayed>d__4(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<itemPrefab>5__2 = null;
				<item>5__3 = null;
				<ex>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0184: Unknown result type (might be due to invalid IL or missing references)
				//IL_018e: Expected O, but got Unknown
				//IL_014d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0157: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<timeout>5__1 = 5f;
					goto IL_008c;
				case 2:
					<>1__state = -1;
					goto IL_008c;
				case 3:
					<>1__state = -1;
					GameUtils.instance.InstantiateAndGrab(<item>5__3, Character.localCharacter, 1);
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 4;
					return true;
				case 4:
					{
						<>1__state = -1;
						goto IL_019f;
					}
					IL_008c:
					if ((Object)(object)Character.localCharacter == (Object)null && <timeout>5__1 > 0f)
					{
						<timeout>5__1 -= Time.unscaledDeltaTime;
						<>2__current = null;
						<>1__state = 2;
						return true;
					}
					if (!((Object)(object)Character.localCharacter != (Object)null))
					{
						break;
					}
					<itemPrefab>5__2 = <>4__this.GetStartingItemForClass(ClassManager.CurrentClass);
					if (!string.IsNullOrEmpty(<itemPrefab>5__2))
					{
						<item>5__3 = null;
						try
						{
							<item>5__3 = ObjectDatabaseAsset<ItemDatabase, Item>.GetObjectFromString(<itemPrefab>5__2);
						}
						catch (Exception ex)
						{
							<ex>5__4 = ex;
							Debug.LogError((object)("[ClassMod-F] Error getting item: " + <ex>5__4.Message));
							return false;
						}
						if ((Object)(object)<item>5__3 != (Object)null)
						{
							<>2__current = (object)new WaitForSeconds(8f);
							<>1__state = 3;
							return true;
						}
						goto IL_019f;
					}
					goto IL_01a7;
					IL_01a7:
					<itemPrefab>5__2 = null;
					break;
					IL_019f:
					<item>5__3 = null;
					goto IL_01a7;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private readonly Harmony _harmony = new Harmony("com.classmod.f");

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			_harmony.PatchAll();
			GameObject val = new GameObject("ClassUI");
			val.AddComponent<ClassUI>();
			Object.DontDestroyOnLoad((Object)(object)val);
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviour)this).StartCoroutine(ResetCooldownsDelayed(scene));
			if (!(((Scene)(ref scene)).name != "Airport"))
			{
			}
		}

		[IteratorStateMachine(typeof(<ResetCooldownsDelayed>d__3))]
		private IEnumerator ResetCooldownsDelayed(Scene scene)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ResetCooldownsDelayed>d__3(0)
			{
				<>4__this = this,
				scene = scene
			};
		}

		[IteratorStateMachine(typeof(<SpawnStartingItemDelayed>d__4))]
		private IEnumerator SpawnStartingItemDelayed(Scene scene)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SpawnStartingItemDelayed>d__4(0)
			{
				<>4__this = this,
				scene = scene
			};
		}

		private string GetStartingItemForClass(PlayerClass cls)
		{
			if (1 == 0)
			{
			}
			string result = cls switch
			{
				PlayerClass.Scout => "Energy Drink", 
				PlayerClass.Herbalist => "FirstAidKit", 
				PlayerClass.Forager => "Kingberry Purple", 
				PlayerClass.Ranger => "Sports Drink", 
				_ => null, 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		private void Update()
		{
			//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();
			if (((Scene)(ref activeScene)).name == "Airport")
			{
				ClassManager.Update();
			}
		}
	}
	public static class ClassAbilities
	{
		private static GameObject _container;

		private static PlayerClass _lastClass = (PlayerClass)(-1);

		public static void AssignAbility(PlayerClass cls)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			if ((Object)(object)Character.localCharacter == (Object)null)
			{
				return;
			}
			if ((Object)(object)_container == (Object)null)
			{
				_container = new GameObject("ClassModF_Abilities");
				Object.DontDestroyOnLoad((Object)(object)_container);
			}
			if (_lastClass != cls || !HasAbilityFor(cls))
			{
				DestroyIfExists<ScoutAbility>();
				DestroyIfExists<ForageAbility>();
				DestroyIfExists<RangerAbility>();
				DestroyIfExists<TinkererAbility>();
				switch (cls)
				{
				case PlayerClass.Scout:
					_container.AddComponent<ScoutAbility>();
					break;
				case PlayerClass.Forager:
					_container.AddComponent<ForageAbility>();
					break;
				case PlayerClass.Herbalist:
					_container.AddComponent<ForageAbility>();
					break;
				case PlayerClass.Ranger:
					_container.AddComponent<RangerAbility>();
					break;
				case PlayerClass.Tinkerer:
					_container.AddComponent<TinkererAbility>();
					break;
				}
				_lastClass = cls;
			}
		}

		private static void DestroyIfExists<T>() where T : Component
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			T val = (((Object)(object)_container != (Object)null) ? _container.GetComponent<T>() : default(T));
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)val);
			}
		}

		private static bool HasAbilityFor(PlayerClass cls)
		{
			if (1 == 0)
			{
			}
			bool result = cls switch
			{
				PlayerClass.Forager => (Object)(object)_container.GetComponent<ForageAbility>() != (Object)null, 
				PlayerClass.Herbalist => (Object)(object)_container.GetComponent<ForageAbility>() != (Object)null, 
				PlayerClass.Scout => (Object)(object)_container.GetComponent<ScoutAbility>() != (Object)null, 
				PlayerClass.Ranger => (Object)(object)_container.GetComponent<RangerAbility>() != (Object)null, 
				PlayerClass.Tinkerer => (Object)(object)_container.GetComponent<TinkererAbility>() != (Object)null, 
				_ => false, 
			};
			if (1 == 0)
			{
			}
			return result;
		}
	}
	public static class ClassModifiers
	{
		public static float GetStaminaMultiplier(PlayerClass playerClass)
		{
			return 1f;
		}

		public static float GetWeightMultiplier(PlayerClass playerClass)
		{
			return 1f;
		}

		public static Dictionary<int, float> GetAllAfflictionMultipliers(PlayerClass playerClass)
		{
			Dictionary<int, float> dictionary = new Dictionary<int, float>();
			for (int i = 0; i < 9; i++)
			{
				dictionary[i] = 1f;
			}
			return dictionary;
		}

		public static float GetAfflictionMultiplier(PlayerClass playerClass, int status)
		{
			return 1f;
		}
	}
	public class ClassUI : MonoBehaviour
	{
		private static readonly Dictionary<int, string> AfflictionNames = new Dictionary<int, string>
		{
			{ 1, "Hunger Rate" },
			{ 2, "Cold Damage" },
			{ 8, "Heat Damage" },
			{ 0, "Fall Damage" },
			{ 3, "Poison Damage" },
			{ 6, "Drowsiness" }
		};

		private static bool showHUD = false;

		private static readonly KeyCode toggleKey = (KeyCode)273;

		private void Awake()
		{
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void Start()
		{
			//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();
			ApplySceneGate(((Scene)(ref activeScene)).name);
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			ApplySceneGate(((Scene)(ref scene)).name);
		}

		private void ApplySceneGate(string sceneName)
		{
			bool enabled = sceneName == "Airport";
			showHUD = false;
			((Behaviour)this).enabled = enabled;
		}

		private void Update()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(toggleKey))
			{
				showHUD = !showHUD;
			}
		}

		private void OnGUI()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			if (!showHUD)
			{
				return;
			}
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				fontSize = 12
			};
			val.normal.textColor = Color.cyan;
			GUIStyle val2 = val;
			GUILayout.BeginArea(new Rect(10f, 20f, 400f, 600f));
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label($"Current Class: {ClassManager.CurrentClass}", val2, Array.Empty<GUILayoutOption>());
			GUILayout.Space(10f);
			foreach (KeyValuePair<int, float> cachedAfflictionMultiplier in ClassManager.CachedAfflictionMultipliers)
			{
				float value = cachedAfflictionMultiplier.Value;
				if (!Mathf.Approximately(value, 1f))
				{
					string arg = (AfflictionNames.ContainsKey(cachedAfflictionMultiplier.Key) ? AfflictionNames[cachedAfflictionMultiplier.Key] : ((object)cachedAfflictionMultiplier.Key).ToString());
					GUILayout.Label($"{arg}: {value}x", val2, Array.Empty<GUILayoutOption>());
				}
			}
			GUILayout.Space(10f);
			string classDescription = GetClassDescription(ClassManager.CurrentClass);
			if (!string.IsNullOrEmpty(classDescription))
			{
				GUILayout.Label("Class Description:", val2, Array.Empty<GUILayoutOption>());
				GUILayout.Label(classDescription, val2, Array.Empty<GUILayoutOption>());
				GUILayout.Space(10f);
			}
			GUILayout.Label("Press ← or → to change class", val2, Array.Empty<GUILayoutOption>());
			GUILayout.Label($"Press {toggleKey} to toggle HUD", val2, Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
			GUILayout.EndArea();
		}

		private string GetClassDescription(PlayerClass playerClass)
		{
			if (1 == 0)
			{
			}
			string result = playerClass switch
			{
				PlayerClass.Scout => "The Scout excels in speed. Ability: Adrenaline Rush - Press F to activate, Push your body into overdrive, moving faster and climbing with speed for a short time. causes Heavy drowsiness after use.", 
				PlayerClass.Forager => "The Forager is a resourceful survivor who gathers food from the land. Ability: Forage Food - Press F to activate, searching the surroundings for edible resources based on the current biome, spawning fruits, berries, or mushrooms. Physically demanding, causes drowsiness after use.", 
				PlayerClass.Herbalist => "The Herbalist specializes in natural remedies and healing. Ability: Forage Herbs - Press F to activate, scanning the area for medicinal items based on the biome, spawning herbs, roots, or healing supplies. Physically demanding, causes drowsiness after use.", 
				PlayerClass.Ranger => "The Ranger masters survival instincts with superior stamina and resilience. Ability: Survival Instinct - Press F to activate, push your limits to add 50 bonus stamina and become invisible for 8 seconds. causes Heavy drowsiness after use.", 
				PlayerClass.Tinkerer => "The Tinkerer is an inventive engineer who crafts useful tools from scavenged parts. Ability: Tinker Tools - Press F to activate, assembles a random equipment from scavenged parts. Highly demanding work, causes significant drowsiness after use.", 
				_ => "", 
			};
			if (1 == 0)
			{
			}
			return result;
		}
	}
	public class ScoutAbility : MonoBehaviour, IAbilityWithCooldown
	{
		[CompilerGenerated]
		private sealed class <ApplyDrowsyAfterDelay>d__18 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Character local;

			public float delay;

			public ScoutAbility <>4__this;

			private Affliction_AdjustDrowsyOverTime <drowsyAffliction>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ApplyDrowsyAfterDelay>d__18(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<drowsyAffliction>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Expected O, but got Unknown
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(delay);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)local != (Object)null)
					{
						<drowsyAffliction>5__1 = new Affliction_AdjustDrowsyOverTime(0.075f, 10f);
						local.refs.afflictions.AddAffliction((Affliction)(object)<drowsyAffliction>5__1, false);
						<drowsyAffliction>5__1 = null;
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public KeyCode abilityKey = (KeyCode)102;

		public float holdTime = 0f;

		public float cooldownSeconds = 600f;

		public float duration = 8f;

		public float moveSpeedMod = 0.5f;

		public float climbSpeedMod = 1.5f;

		public float drowsyOnEnd = 0.75f;

		public float injuryOnEnd;

		public float climbDelay;

		private float _hold;

		private float _cooldownLeft;

		private bool _uiAvailable;

		private CooldownUI? _ui;

		private void Start()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				_ui = CooldownUI.Get("Scout FasterBoi", new Vector2(-20f, 140f));
				_uiAvailable = true;
				_ui.Hide();
			}
			catch
			{
				_uiAvailable = false;
			}
		}

		private void Update()
		{
			//IL_0018: 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_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null)
			{
				return;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name == "Airport")
			{
				if (_uiAvailable && _ui != null)
				{
					_ui.Hide();
				}
				return;
			}
			if (ClassManager.CurrentClass != PlayerClass.Scout)
			{
				if (_uiAvailable && _ui != null)
				{
					_ui.Hide();
				}
				return;
			}
			if (_uiAvailable && _ui != null)
			{
				_ui.Show();
			}
			if (_cooldownLeft > 0f)
			{
				_cooldownLeft -= Time.deltaTime;
				if (_cooldownLeft < 0f)
				{
					_cooldownLeft = 0f;
				}
			}
			if (_uiAvailable && _ui != null)
			{
				_ui.Update();
			}
			if (_cooldownLeft > 0f)
			{
				if (Input.GetKeyUp(abilityKey))
				{
					_hold = 0f;
				}
				return;
			}
			if (Input.GetKey(abilityKey))
			{
				_hold += Time.deltaTime;
				if (_hold >= holdTime)
				{
					_hold = 0f;
					Activate(localCharacter);
				}
			}
			if (Input.GetKeyUp(abilityKey))
			{
				_hold = 0f;
			}
		}

		private void OnDisable()
		{
			if (_ui != null)
			{
				_ui.Hide();
			}
		}

		private void OnDestroy()
		{
			if (_ui != null)
			{
				_ui.Hide();
			}
		}

		private void Activate(Character local)
		{
			//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_0013: 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_002b: 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_0043: Expected O, but got Unknown
			try
			{
				Affliction_FasterBoi val = new Affliction_FasterBoi
				{
					totalTime = duration,
					moveSpeedMod = moveSpeedMod,
					climbSpeedMod = climbSpeedMod,
					drowsyOnEnd = 0f,
					climbDelay = climbDelay
				};
				local.refs.afflictions.AddAffliction((Affliction)(object)val, false);
				((MonoBehaviour)this).StartCoroutine(ApplyDrowsyAfterDelay(local, duration));
				_cooldownLeft = cooldownSeconds;
				if (_uiAvailable && _ui != null)
				{
					_ui.StartCooldown(cooldownSeconds);
				}
				Debug.Log((object)($"[ScoutAbility] Activated: duration {duration}s, " + $"speed x{moveSpeedMod}, climb x{climbSpeedMod}, " + $"drowsy {drowsyOnEnd} per second for 10s after end."));
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"[ScoutAbility] Exception: {arg}");
			}
		}

		[IteratorStateMachine(typeof(<ApplyDrowsyAfterDelay>d__18))]
		private IEnumerator ApplyDrowsyAfterDelay(Character local, float delay)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ApplyDrowsyAfterDelay>d__18(0)
			{
				<>4__this = this,
				local = local,
				delay = delay
			};
		}

		public void ResetCooldown()
		{
			_cooldownLeft = 0f;
			if (_uiAvailable && _ui != null)
			{
				_ui.StartCooldown(0f);
				_ui.Show();
			}
		}
	}
	public enum ForageBiomeType
	{
		Shore,
		Tropics,
		Roots,
		Alpine,
		Mesa,
		Caldera,
		Kiln,
		Peak
	}
	public class ForageAbility : MonoBehaviour, IAbilityWithCooldown
	{
		[CompilerGenerated]
		private sealed class <SpawnForageItemDelayed>d__12 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string itemPrefab;

			public Character local;

			public ForageAbility <>4__this;

			private Item <item>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SpawnForageItemDelayed>d__12(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<item>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (!string.IsNullOrEmpty(itemPrefab) && (Object)local != (Object)null)
					{
						<item>5__1 = ObjectDatabaseAsset<ItemDatabase, Item>.GetObjectFromString(itemPrefab);
						if ((Object)(object)<item>5__1 != (Object)null)
						{
							GameUtils.instance.InstantiateAndGrab(<item>5__1, local, 1);
						}
						<item>5__1 = null;
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public KeyCode abilityKey = (KeyCode)102;

		public float holdTime = 0f;

		public float cooldownSeconds = 300f;

		private float _hold;

		private float _cooldownLeft;

		private bool _uiAvailable;

		private CooldownUI? _ui;

		private void Start()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				_ui = CooldownUI.Get("Forage Ability", new Vector2(-20f, 140f));
				_uiAvailable = true;
				_ui.Hide();
			}
			catch
			{
				_uiAvailable = false;
			}
		}

		private void Update()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			Character localCharacter = Character.localCharacter;
			if ((Object)localCharacter == (Object)null)
			{
				return;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name == "Airport")
			{
				if (_uiAvailable && _ui != null)
				{
					_ui.Hide();
				}
				return;
			}
			if (ClassManager.CurrentClass != PlayerClass.Herbalist && ClassManager.CurrentClass != PlayerClass.Forager)
			{
				if (_uiAvailable && _ui != null)
				{
					_ui.Hide();
				}
				return;
			}
			if (_uiAvailable && _ui != null)
			{
				_ui.Show();
			}
			if (_cooldownLeft > 0f)
			{
				_cooldownLeft -= Time.deltaTime;
				if (_cooldownLeft < 0f)
				{
					_cooldownLeft = 0f;
				}
			}
			if (_uiAvailable && _ui != null)
			{
				_ui.Update();
			}
			if (_cooldownLeft > 0f)
			{
				if (Input.GetKeyUp(abilityKey))
				{
					_hold = 0f;
				}
				return;
			}
			if (Input.GetKey(abilityKey))
			{
				_hold += Time.deltaTime;
				if (_hold >= holdTime)
				{
					_hold = 0f;
					TryForage(localCharacter);
				}
			}
			if (Input.GetKeyUp(abilityKey))
			{
				_hold = 0f;
			}
		}

		private void OnDisable()
		{
			if (_ui != null)
			{
				_ui.Hide();
			}
		}

		private void OnDestroy()
		{
			if (_ui != null)
			{
				_ui.Hide();
			}
		}

		private void TryForage(Character local)
		{
			try
			{
				string forageItemForBiome = GetForageItemForBiome();
				string forageMessage = GetForageMessage(forageItemForBiome);
				if (!string.IsNullOrEmpty(forageMessage))
				{
					RestrictionPopup.ShowMessage(forageMessage, 5f);
				}
				else if (string.IsNullOrEmpty(forageItemForBiome))
				{
					RestrictionPopup.ShowMessage("you find nothing worth taking", 5f);
				}
				if (!string.IsNullOrEmpty(forageItemForBiome))
				{
					((MonoBehaviour)this).StartCoroutine(SpawnForageItemDelayed(forageItemForBiome, local));
				}
				local.refs.afflictions.AddStatus((STATUSTYPE)6, 0.25f, false, true, true);
				_cooldownLeft = cooldownSeconds;
				if (_uiAvailable && _ui != null)
				{
					_ui.StartCooldown(cooldownSeconds);
				}
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"[ForageAbility] Exception: {arg}");
			}
		}

		[IteratorStateMachine(typeof(<SpawnForageItemDelayed>d__12))]
		private IEnumerator SpawnForageItemDelayed(string itemPrefab, Character local)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SpawnForageItemDelayed>d__12(0)
			{
				<>4__this = this,
				itemPrefab = itemPrefab,
				local = local
			};
		}

		private string GetForageItemForBiome()
		{
			if (ClassManager.CurrentClass == PlayerClass.Forager)
			{
				return GetForageFood();
			}
			if (ClassManager.CurrentClass == PlayerClass.Herbalist)
			{
				return GetForageHerbs();
			}
			return null;
		}

		private ForageBiomeType GetCurrentBiome()
		{
			//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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected I4, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Invalid comparison between Unknown and I4
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Invalid comparison between Unknown and I4
			try
			{
				MapHandler instance = Singleton<MapHandler>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					Segment currentSegment = instance.GetCurrentSegment();
					BiomeType currentBiome = instance.GetCurrentBiome();
					switch ((int)currentSegment)
					{
					case 3:
						return ForageBiomeType.Caldera;
					case 4:
						return ForageBiomeType.Kiln;
					case 5:
						return ForageBiomeType.Peak;
					case 1:
						if ((int)currentBiome == 7)
						{
							return ForageBiomeType.Roots;
						}
						return ForageBiomeType.Tropics;
					case 2:
						if ((int)currentBiome == 2)
						{
							return ForageBiomeType.Alpine;
						}
						return ForageBiomeType.Mesa;
					default:
						return ForageBiomeType.Shore;
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[ForageAbility] Error getting biome: " + ex.Message));
			}
			return ForageBiomeType.Shore;
		}

		private string GetForageFood()
		{
			ForageBiomeType currentBiome = GetCurrentBiome();
			List<(string, float)> list = new List<(string, float)>();
			switch (currentBiome)
			{
			case ForageBiomeType.Shore:
				list.Add(("Item_Coconut", 1f));
				list.Add(("Apple Berry Red", 1f));
				list.Add(("Apple Berry Yellow", 1f));
				list.Add(("Mushroom Normie", 1f));
				list.Add(("Mushroom Lace", 1f));
				list.Add(("Mushroom Cluster", 1f));
				list.Add(("Mushroom Chubby", 1f));
				break;
			case ForageBiomeType.Tropics:
				list.Add(("Item_Coconut", 1f));
				list.Add(("Apple Berry Red", 1f));
				list.Add(("Apple Berry Yellow", 1f));
				list.Add(("Pepper Berry", 1f));
				list.Add(("Berrynana Yellow", 1f));
				list.Add(("Berrynana Blue", 1f));
				list.Add(("Berrynana Brown", 1f));
				list.Add(("Clusterberry Yellow", 1f));
				list.Add(("Clusterberry Black", 1f));
				list.Add(("Mushroom Normie", 1f));
				list.Add(("Mushroom Lace", 1f));
				list.Add(("Mushroom Cluster", 1f));
				list.Add(("Mushroom Chubby", 1f));
				list.Add(("Kingberry Purple", 1f));
				break;
			case ForageBiomeType.Roots:
				list.Add(("Shroomberry_Red", 1f));
				list.Add(("Shroomberry_Yellow", 1f));
				list.Add(("Shroomberry_Purple", 0.5f));
				list.Add(("Mushroom Normie", 1f));
				list.Add(("Mushroom Lace", 1f));
				list.Add(("Mushroom Cluster", 1f));
				list.Add(("Mushroom Chubby", 1f));
				break;
			case ForageBiomeType.Alpine:
				list.Add(("Winterberry Orange", 1f));
				list.Add(("Napberry", 0.1f));
				break;
			case ForageBiomeType.Mesa:
				list.Add(("Item_Coconut", 1f));
				list.Add(("Prickleberry_Red", 1f));
				list.Add(("Mushroom Normie", 1f));
				list.Add(("Mushroom Lace", 1f));
				list.Add(("Mushroom Cluster", 1f));
				list.Add(("Mushroom Chubby", 1f));
				break;
			case ForageBiomeType.Caldera:
				list.Add(("NestEgg", 1f));
				break;
			case ForageBiomeType.Kiln:
				list.Add(("Airplane Food", 1f));
				list.Add(("Granola Bar", 1f));
				list.Add(("TrailMix", 1f));
				break;
			default:
				return null;
			}
			return SelectWeightedItem(list);
		}

		private string GetForageHerbs()
		{
			ForageBiomeType currentBiome = GetCurrentBiome();
			List<(string, float)> list = new List<(string, float)>();
			switch (currentBiome)
			{
			case ForageBiomeType.Shore:
				list.Add(("MedicinalRoot", 1f));
				list.Add(("HealingPuffShroom", 0.5f));
				break;
			case ForageBiomeType.Tropics:
				list.Add(("MedicinalRoot", 1f));
				list.Add(("Clusterberry Red", 1f));
				list.Add(("HealingPuffShroom", 0.5f));
				break;
			case ForageBiomeType.Roots:
				list.Add(("MedicinalRoot", 1f));
				list.Add(("HealingPuffShroom", 0.5f));
				break;
			case ForageBiomeType.Alpine:
				list.Add(("HealingPuffShroom", 1f));
				list.Add(("Winterberry Yellow", 0.5f));
				list.Add(("Napberry", 0.1f));
				break;
			case ForageBiomeType.Mesa:
				list.Add(("Prickleberry_Gold", 1f));
				list.Add(("HealingPuffShroom", 0.5f));
				break;
			case ForageBiomeType.Caldera:
				list.Add(("Sports Drink", 1f));
				break;
			case ForageBiomeType.Kiln:
				list.Add(("Lollipop", 1f));
				list.Add(("Energy Drink", 1f));
				list.Add(("FortifiedMilk", 1f));
				list.Add(("Sports Drink", 1f));
				break;
			default:
				return null;
			}
			return SelectWeightedItem(list);
		}

		private string SelectWeightedItem(List<(string item, float weight)> weightedItems)
		{
			if (weightedItems == null || weightedItems.Count == 0)
			{
				return null;
			}
			float num = 0f;
			foreach (var weightedItem in weightedItems)
			{
				num += weightedItem.weight;
			}
			float num2 = Random.value * num;
			float num3 = 0f;
			foreach (var weightedItem2 in weightedItems)
			{
				num3 += weightedItem2.weight;
				if (num2 <= num3)
				{
					return weightedItem2.item;
				}
			}
			return weightedItems[weightedItems.Count - 1].item;
		}

		private string GetForageMessage(string itemFound)
		{
			if (string.IsNullOrEmpty(itemFound))
			{
				return null;
			}
			ForageBiomeType currentBiome = GetCurrentBiome();
			if (ClassManager.CurrentClass == PlayerClass.Forager)
			{
				if (currentBiome == ForageBiomeType.Kiln)
				{
					return "you find something in a luggage";
				}
			}
			else if (ClassManager.CurrentClass == PlayerClass.Herbalist && (currentBiome == ForageBiomeType.Caldera || currentBiome == ForageBiomeType.Kiln))
			{
				return "you find something in a luggage";
			}
			return null;
		}

		public void ResetCooldown()
		{
			_cooldownLeft = 0f;
			if (_uiAvailable && _ui != null)
			{
				_ui.StartCooldown(0f);
				_ui.Show();
			}
		}
	}
	public class RangerAbility : MonoBehaviour, IAbilityWithCooldown
	{
		[CompilerGenerated]
		private sealed class <ApplyDrowsyAfterDelay>d__15 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Character local;

			public float delay;

			public RangerAbility <>4__this;

			private Affliction_AdjustDrowsyOverTime <drowsyAffliction>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ApplyDrowsyAfterDelay>d__15(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<drowsyAffliction>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Expected O, but got Unknown
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(delay);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)local != (Object)null)
					{
						<drowsyAffliction>5__1 = new Affliction_AdjustDrowsyOverTime(0.075f, 10f);
						local.refs.afflictions.AddAffliction((Affliction)(object)<drowsyAffliction>5__1, false);
						<drowsyAffliction>5__1 = null;
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public KeyCode abilityKey = (KeyCode)102;

		public float holdTime = 0f;

		public float cooldownSeconds = 600f;

		public int effectType = 6;

		public float drowsyAmount = 7.5f;

		private float _hold;

		private float _cooldownLeft;

		private bool _uiAvailable;

		private CooldownUI? _ui;

		private void Start()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				_ui = CooldownUI.Get("NapBerry Ability", new Vector2(-20f, 140f));
				_uiAvailable = true;
				_ui.Hide();
			}
			catch
			{
				_uiAvailable = false;
			}
		}

		private void Update()
		{
			//IL_0018: 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_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null)
			{
				return;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name == "Airport")
			{
				if (_uiAvailable && _ui != null)
				{
					_ui.Hide();
				}
				return;
			}
			if (ClassManager.CurrentClass != PlayerClass.Ranger)
			{
				if (_uiAvailable && _ui != null)
				{
					_ui.Hide();
				}
				return;
			}
			if (_uiAvailable && _ui != null)
			{
				_ui.Show();
			}
			if (_cooldownLeft > 0f)
			{
				_cooldownLeft -= Time.deltaTime;
				if (_cooldownLeft < 0f)
				{
					_cooldownLeft = 0f;
				}
			}
			if (_uiAvailable && _ui != null)
			{
				_ui.Update();
				if (_cooldownLeft <= 0f)
				{
					_ui.Show();
				}
			}
			if (_cooldownLeft > 0f)
			{
				if (Input.GetKeyUp(abilityKey))
				{
					_hold = 0f;
				}
				return;
			}
			if (Input.GetKey(abilityKey))
			{
				_hold += Time.deltaTime;
				if (_hold >= holdTime)
				{
					_hold = 0f;
					ApplyNapBerry(localCharacter);
				}
			}
			if (Input.GetKeyUp(abilityKey))
			{
				_hold = 0f;
			}
		}

		private void OnDisable()
		{
			if (_ui != null)
			{
				_ui.Hide();
			}
		}

		private void OnDestroy()
		{
			if (_ui != null)
			{
				_ui.Hide();
			}
		}

		private void ApplyNapBerry(Character local)
		{
			//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_0013: Expected O, but got Unknown
			try
			{
				Affliction_Invincibility val = new Affliction_Invincibility
				{
					totalTime = 8f
				};
				local.refs.afflictions.AddAffliction((Affliction)(object)val, false);
				local.AddExtraStamina(0.5f);
				((MonoBehaviour)this).StartCoroutine(ApplyDrowsyAfterDelay(local, 8f));
				_cooldownLeft = cooldownSeconds;
				if (_uiAvailable && _ui != null)
				{
					_ui.StartCooldown(cooldownSeconds);
				}
				Debug.Log((object)"[RangerAbility] Activated Survival Instinct: 8s invincibility + 50% bonus stamina, then drowsy.");
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"[RangerAbility] Exception: {arg}");
			}
		}

		public void ResetCooldown()
		{
			_cooldownLeft = 0f;
			if (_uiAvailable && _ui != null)
			{
				_ui.StartCooldown(0f);
				_ui.Show();
			}
		}

		[IteratorStateMachine(typeof(<ApplyDrowsyAfterDelay>d__15))]
		private IEnumerator ApplyDrowsyAfterDelay(Character local, float delay)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ApplyDrowsyAfterDelay>d__15(0)
			{
				<>4__this = this,
				local = local,
				delay = delay
			};
		}
	}
	public class TinkererAbility : MonoBehaviour, IAbilityWithCooldown
	{
		[CompilerGenerated]
		private sealed class <SpawnTinkerItemDelayed>d__12 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string itemPrefab;

			public Character local;

			public TinkererAbility <>4__this;

			private Item <item>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SpawnTinkerItemDelayed>d__12(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<item>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (!string.IsNullOrEmpty(itemPrefab) && (Object)local != (Object)null)
					{
						<item>5__1 = ObjectDatabaseAsset<ItemDatabase, Item>.GetObjectFromString(itemPrefab);
						if ((Object)(object)<item>5__1 != (Object)null)
						{
							GameUtils.instance.InstantiateAndGrab(<item>5__1, local, 1);
						}
						<item>5__1 = null;
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public KeyCode abilityKey = (KeyCode)102;

		public float holdTime = 0f;

		public float cooldownSeconds = 600f;

		private float _hold;

		private float _cooldownLeft;

		private bool _uiAvailable;

		private CooldownUI? _ui;

		private void Start()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				_ui = CooldownUI.Get("Tinker Ability", new Vector2(-20f, 140f));
				_uiAvailable = true;
				_ui.Hide();
			}
			catch
			{
				_uiAvailable = false;
			}
		}

		private void Update()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			Character localCharacter = Character.localCharacter;
			if ((Object)localCharacter == (Object)null)
			{
				return;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name == "Airport")
			{
				if (_uiAvailable && _ui != null)
				{
					_ui.Hide();
				}
				return;
			}
			if (ClassManager.CurrentClass != PlayerClass.Tinkerer)
			{
				if (_uiAvailable && _ui != null)
				{
					_ui.Hide();
				}
				return;
			}
			if (_uiAvailable && _ui != null)
			{
				_ui.Show();
			}
			if (_cooldownLeft > 0f)
			{
				_cooldownLeft -= Time.deltaTime;
				if (_cooldownLeft < 0f)
				{
					_cooldownLeft = 0f;
				}
			}
			if (_uiAvailable && _ui != null)
			{
				_ui.Update();
			}
			if (_cooldownLeft > 0f)
			{
				if (Input.GetKeyUp(abilityKey))
				{
					_hold = 0f;
				}
				return;
			}
			if (Input.GetKey(abilityKey))
			{
				_hold += Time.deltaTime;
				if (_hold >= holdTime)
				{
					_hold = 0f;
					TryTinker(localCharacter);
				}
			}
			if (Input.GetKeyUp(abilityKey))
			{
				_hold = 0f;
			}
		}

		private void OnDisable()
		{
			if (_ui != null)
			{
				_ui.Hide();
			}
		}

		private void OnDestroy()
		{
			if (_ui != null)
			{
				_ui.Hide();
			}
		}

		private void TryTinker(Character local)
		{
			try
			{
				string tinkerItemForBiome = GetTinkerItemForBiome();
				string tinkerMessage = GetTinkerMessage(tinkerItemForBiome);
				if (!string.IsNullOrEmpty(tinkerMessage))
				{
					RestrictionPopup.ShowMessage(tinkerMessage, 5f);
				}
				else if (string.IsNullOrEmpty(tinkerItemForBiome))
				{
					RestrictionPopup.ShowMessage("you find nothing worth tinkering with", 5f);
				}
				if (!string.IsNullOrEmpty(tinkerItemForBiome))
				{
					((MonoBehaviour)this).StartCoroutine(SpawnTinkerItemDelayed(tinkerItemForBiome, local));
				}
				local.refs.afflictions.AddStatus((STATUSTYPE)6, 0.5f, false, true, true);
				_cooldownLeft = cooldownSeconds;
				if (_uiAvailable && _ui != null)
				{
					_ui.StartCooldown(cooldownSeconds);
				}
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"[TinkererAbility] Exception: {arg}");
			}
		}

		[IteratorStateMachine(typeof(<SpawnTinkerItemDelayed>d__12))]
		private IEnumerator SpawnTinkerItemDelayed(string itemPrefab, Character local)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SpawnTinkerItemDelayed>d__12(0)
			{
				<>4__this = this,
				itemPrefab = itemPrefab,
				local = local
			};
		}

		private string GetTinkerItemForBiome()
		{
			ForageBiomeType currentBiome = GetCurrentBiome();
			List<(string, float)> list = new List<(string, float)>();
			switch (currentBiome)
			{
			case ForageBiomeType.Shore:
				list.Add(("ClimbingSpike", 1f));
				list.Add(("PortableStovetopItem", 0.5f));
				list.Add(("RopeShooter", 1f));
				list.Add(("RopeSpool", 1f));
				list.Add(("ScoutCannonItem", 1f));
				break;
			case ForageBiomeType.Tropics:
				list.Add(("ClimbingSpike", 1f));
				list.Add(("PortableStovetopItem", 0.5f));
				list.Add(("RopeShooter", 1f));
				list.Add(("RopeSpool", 1f));
				list.Add(("ScoutCannonItem", 1f));
				break;
			case ForageBiomeType.Roots:
				list.Add(("ClimbingSpike", 1f));
				list.Add(("PortableStovetopItem", 0.5f));
				list.Add(("RopeShooter", 1f));
				list.Add(("RopeSpool", 1f));
				list.Add(("ScoutCannonItem", 1f));
				break;
			case ForageBiomeType.Alpine:
				list.Add(("ClimbingSpike", 1f));
				list.Add(("PortableStovetopItem", 0.5f));
				list.Add(("RopeShooter", 1f));
				list.Add(("RopeSpool", 1f));
				list.Add(("ScoutCannonItem", 1f));
				break;
			case ForageBiomeType.Mesa:
				list.Add(("ClimbingSpike", 1f));
				list.Add(("PortableStovetopItem", 0.5f));
				list.Add(("RopeShooter", 1f));
				list.Add(("RopeSpool", 1f));
				list.Add(("ScoutCannonItem", 1f));
				break;
			case ForageBiomeType.Caldera:
				list.Add(("ClimbingSpike", 1f));
				list.Add(("PortableStovetopItem", 0.5f));
				list.Add(("RopeShooter", 1f));
				list.Add(("RopeSpool", 1f));
				list.Add(("ScoutCannonItem", 1f));
				break;
			case ForageBiomeType.Kiln:
				list.Add(("ClimbingSpike", 1f));
				list.Add(("PortableStovetopItem", 0.5f));
				list.Add(("RopeShooter", 1f));
				list.Add(("RopeSpool", 1f));
				list.Add(("ScoutCannonItem", 1f));
				break;
			default:
				return null;
			}
			return SelectWeightedItem(list);
		}

		private ForageBiomeType GetCurrentBiome()
		{
			//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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected I4, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Invalid comparison between Unknown and I4
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Invalid comparison between Unknown and I4
			try
			{
				MapHandler instance = Singleton<MapHandler>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					Segment currentSegment = instance.GetCurrentSegment();
					BiomeType currentBiome = instance.GetCurrentBiome();
					switch ((int)currentSegment)
					{
					case 3:
						return ForageBiomeType.Caldera;
					case 4:
						return ForageBiomeType.Kiln;
					case 5:
						return ForageBiomeType.Peak;
					case 1:
						if ((int)currentBiome == 7)
						{
							return ForageBiomeType.Roots;
						}
						return ForageBiomeType.Tropics;
					case 2:
						if ((int)currentBiome == 2)
						{
							return ForageBiomeType.Alpine;
						}
						return ForageBiomeType.Mesa;
					default:
						return ForageBiomeType.Shore;
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[TinkererAbility] Error getting biome: " + ex.Message));
			}
			return ForageBiomeType.Shore;
		}

		private string SelectWeightedItem(List<(string item, float weight)> weightedItems)
		{
			if (weightedItems == null || weightedItems.Count == 0)
			{
				return null;
			}
			float num = 0f;
			foreach (var weightedItem in weightedItems)
			{
				num += weightedItem.weight;
			}
			float num2 = Random.value * num;
			float num3 = 0f;
			foreach (var weightedItem2 in weightedItems)
			{
				num3 += weightedItem2.weight;
				if (num2 <= num3)
				{
					return weightedItem2.item;
				}
			}
			return weightedItems[weightedItems.Count - 1].item;
		}

		private string GetTinkerMessage(string itemFound)
		{
			if (string.IsNullOrEmpty(itemFound))
			{
				return null;
			}
			ForageBiomeType currentBiome = GetCurrentBiome();
			if (currentBiome == ForageBiomeType.Kiln)
			{
				return "you tinker together some useful tools";
			}
			return null;
		}

		public void ResetCooldown()
		{
			_cooldownLeft = 0f;
			if (_uiAvailable && _ui != null)
			{
				_ui.StartCooldown(0f);
				_ui.Show();
			}
		}
	}
}