Decompiled source of Pilgrim v0.6.0

plugins/Pilgrim.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using YamlDotNet.RepresentationModel;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

[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("Pilgrim")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+6db3350c13e1111dc7580d6ca5b09f1dd95e8c50")]
[assembly: AssemblyProduct("Pilgrim")]
[assembly: AssemblyTitle("Pilgrim")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace EnvReporter
{
	internal sealed class BoonChooserUI : MonoBehaviour
	{
		private class BoonBtn
		{
			public Button btn;

			public Image bg;

			public Image hi;

			public Image halo;

			public Image[] border;

			public TextMeshProUGUI rarity;

			public TextMeshProUGUI name;

			public TextMeshProUGUI[] lines;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Action <>9__20_0;

			public static UnityAction <>9__20_1;

			internal void <BuildUI>b__20_0()
			{
				BoonHud.RequestClose();
			}

			internal void <BuildUI>b__20_1()
			{
				BoonHud.DoReroll();
			}
		}

		private static BoonChooserUI _inst;

		private static readonly Color[] RarityCol = (Color[])(object)new Color[4]
		{
			new Color(0.85f, 0.82f, 0.72f),
			new Color(0.42f, 0.62f, 0.96f),
			new Color(0.96f, 0.86f, 0.32f),
			new Color(0.96f, 0.56f, 0.22f)
		};

		private static readonly string[] RarityName = new string[4] { "Common", "Uncommon", "Rare", "Unique" };

		private const float BW = 244f;

		private const float BH = 214f;

		private const float BGAP = 16f;

		private const float PAD = 24f;

		private const float TITLE_H = 48f;

		private const float REROLL_H = 46f;

		private GameObject _root;

		private bool _built;

		private float _basePPU = 1f;

		private Image _panel;

		private TextMeshProUGUI _title;

		private int _hoverIdx = -1;

		private Button _rerollBtn;

		private TextMeshProUGUI _rerollLabel;

		private readonly BoonBtn[] _boons = new BoonBtn[3];

		private bool _wasShown;

		private int _hoverSettle;

		private string _appliedSprite = " ";

		internal static void Ensure()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)_inst != (Object)null))
			{
				GameObject val = new GameObject("PilgrimBoonChooser");
				Object.DontDestroyOnLoad((Object)val);
				_inst = val.AddComponent<BoonChooserUI>();
			}
		}

		private void BuildUI()
		{
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Expected O, but got Unknown
			Canvas val = (((Object)(object)InventoryGui.instance != (Object)null) ? ((Component)InventoryGui.instance).GetComponentInParent<Canvas>() : null) ?? (((Object)(object)Hud.instance != (Object)null) ? ((Component)Hud.instance).GetComponentInParent<Canvas>() : null);
			Transform transform;
			if ((Object)(object)val != (Object)null)
			{
				_root = new GameObject("PilgrimBoonChooserRoot", new Type[1] { typeof(RectTransform) });
				_root.transform.SetParent(((Component)val).transform, false);
				RectTransform val2 = (RectTransform)_root.transform;
				val2.anchorMin = Vector2.zero;
				val2.anchorMax = Vector2.one;
				val2.offsetMin = Vector2.zero;
				val2.offsetMax = Vector2.zero;
				_root.transform.SetAsLastSibling();
				transform = _root.transform;
			}
			else
			{
				GameObject val3 = new GameObject("Canvas", new Type[1] { typeof(RectTransform) });
				val3.transform.SetParent(((Component)this).transform, false);
				Canvas obj = val3.AddComponent<Canvas>();
				obj.renderMode = (RenderMode)0;
				obj.sortingOrder = 5100;
				val3.AddComponent<CanvasScaler>();
				val3.AddComponent<GraphicRaycaster>();
				_root = val3;
				transform = val3.transform;
			}
			Image obj2 = UiKit.Img("Dim", transform, UiKit.Solid(), new Color(0f, 0f, 0f, 0.6f), (Type)0);
			((Graphic)obj2).raycastTarget = true;
			UiKit.Stretch(((Graphic)obj2).rectTransform);
			AddTrigger(((Component)obj2).gameObject.AddComponent<EventTrigger>(), (EventTriggerType)4, delegate
			{
				BoonHud.RequestClose();
			});
			float num = 812f;
			float num2 = 382f;
			_panel = UiKit.Img("ChooserPanel", transform, UiKit.Solid(), Color.white, (Type)1);
			string preferName = (string.IsNullOrEmpty(BoonCfg.ChooserPanelSprite) ? CharSheetCfg.PanelSprite : BoonCfg.ChooserPanelSprite);
			UiKit.StylePanel(_panel, preferName);
			_panel.type = (Type)1;
			_basePPU = _panel.pixelsPerUnitMultiplier;
			((Graphic)_panel).raycastTarget = true;
			Place(((Graphic)_panel).rectTransform, new Vector2(0.5f, 0.5f), new Vector2(num, num2), Vector2.zero);
			_title = UiKit.Text("Header", ((Component)_panel).transform, 28, UiKit.Gold, (TextAlignmentOptions)514);
			((TMP_Text)_title).fontStyle = (FontStyles)1;
			((TMP_Text)_title).text = "The gods offer a choice";
			((TMP_Text)_title).outlineColor = Color32.op_Implicit(Color.black);
			((TMP_Text)_title).outlineWidth = 0.2f;
			Place(((TMP_Text)_title).rectTransform, new Vector2(0.5f, 0.5f), new Vector2(num - 40f, 48f), new Vector2(0f, num2 / 2f - 24f - 24f));
			float rowY = num2 / 2f - 24f - 48f - 10f - 107f;
			for (int num3 = 0; num3 < 3; num3++)
			{
				_boons[num3] = BuildBoon(num3, rowY);
			}
			_rerollBtn = UiKit.CloneButton(((Component)_panel).transform, "Reroll");
			if ((Object)(object)_rerollBtn != (Object)null)
			{
				RectTransform val4 = (RectTransform)((Component)_rerollBtn).transform;
				Vector2 val5 = default(Vector2);
				((Vector2)(ref val5))..ctor(0.5f, 0.5f);
				val4.anchorMax = val5;
				val4.anchorMin = val5;
				val4.pivot = new Vector2(0.5f, 0.5f);
				val4.sizeDelta = new Vector2(180f, 46f);
				val4.anchoredPosition = new Vector2(0f, 0f - (num2 / 2f - 24f - 23f));
				ButtonClickedEvent onClick = _rerollBtn.onClick;
				object obj3 = <>c.<>9__20_1;
				if (obj3 == null)
				{
					UnityAction val6 = delegate
					{
						BoonHud.DoReroll();
					};
					<>c.<>9__20_1 = val6;
					obj3 = (object)val6;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj3);
				_rerollLabel = ((Component)_rerollBtn).GetComponentInChildren<TextMeshProUGUI>();
			}
			_built = true;
		}

		private BoonBtn BuildBoon(int i, float rowY)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Expected O, but got Unknown
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			Button val = UiKit.CloneButton(((Component)_panel).transform, "");
			BoonBtn boonBtn = new BoonBtn
			{
				btn = val
			};
			if ((Object)(object)val == (Object)null)
			{
				return boonBtn;
			}
			RectTransform val2 = (RectTransform)((Component)val).transform;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			val2.anchorMax = val3;
			val2.anchorMin = val3;
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.sizeDelta = new Vector2(244f, 214f);
			val2.anchoredPosition = new Vector2((float)(i - 1) * 260f, rowY);
			boonBtn.halo = UiKit.Img($"Halo{i}", ((Component)_panel).transform, UiKit.SoftBoxGlow(), UiKit.Gold, (Type)0);
			RectTransform rectTransform = ((Graphic)boonBtn.halo).rectTransform;
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			rectTransform.anchorMax = val3;
			rectTransform.anchorMin = val3;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.sizeDelta = new Vector2(328f, 298f);
			rectTransform.anchoredPosition = new Vector2((float)(i - 1) * 260f, rowY);
			((Graphic)boonBtn.halo).raycastTarget = false;
			((Component)boonBtn.halo).transform.SetAsFirstSibling();
			((Component)boonBtn.halo).gameObject.SetActive(false);
			TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Component)componentInChildren).gameObject.SetActive(false);
			}
			ref Image bg = ref boonBtn.bg;
			Graphic targetGraphic = ((Selectable)val).targetGraphic;
			bg = (Image)(((object)((targetGraphic is Image) ? targetGraphic : null)) ?? ((object)((Component)val).GetComponent<Image>()));
			if ((Object)(object)boonBtn.bg != (Object)null && !string.IsNullOrEmpty(BoonCfg.ChooserCardSprite))
			{
				Sprite val4 = UiKit.FindSprite(BoonCfg.ChooserCardSprite);
				if ((Object)(object)val4 != (Object)null)
				{
					boonBtn.bg.sprite = val4;
					((Graphic)boonBtn.bg).material = null;
					boonBtn.bg.type = (Type)1;
				}
			}
			if ((Object)(object)boonBtn.bg != (Object)null)
			{
				((Graphic)boonBtn.bg).color = new Color(0.7f, 0.7f, 0.7f);
			}
			((Selectable)val).transition = (Transition)0;
			Image val5 = UiKit.Img($"Hi{i}", ((Component)val).transform, UiKit.Solid(), new Color(0f, 0f, 0f, 0.4f), (Type)0);
			UiKit.Stretch(((Graphic)val5).rectTransform);
			((Graphic)val5).raycastTarget = false;
			((Component)val5).gameObject.SetActive(false);
			boonBtn.hi = val5;
			int idx = i;
			((UnityEvent)val.onClick).AddListener((UnityAction)delegate
			{
				BoonHud.PickIndex(idx);
			});
			EventTrigger et = ((Component)val).gameObject.AddComponent<EventTrigger>();
			AddTrigger(et, (EventTriggerType)0, delegate
			{
				_hoverIdx = idx;
			});
			AddTrigger(et, (EventTriggerType)1, delegate
			{
				if (_hoverIdx == idx)
				{
					_hoverIdx = -1;
				}
			});
			boonBtn.border = MakeBorder(((Component)val).transform, 9f);
			boonBtn.rarity = Child(((Component)val).transform, 20, 62f, body: false);
			boonBtn.name = Child(((Component)val).transform, 24, 26f, body: false);
			((TMP_Text)boonBtn.name).enableWordWrapping = true;
			((TMP_Text)boonBtn.name).fontStyle = (FontStyles)1;
			((TMP_Text)boonBtn.name).outlineColor = Color32.op_Implicit(Color.black);
			((TMP_Text)boonBtn.name).outlineWidth = 0.25f;
			boonBtn.lines = (TextMeshProUGUI[])(object)new TextMeshProUGUI[4];
			for (int num = 0; num < 4; num++)
			{
				boonBtn.lines[num] = Child(((Component)val).transform, 19, -18f - (float)num * 16f, body: true);
			}
			return boonBtn;
		}

		private TextMeshProUGUI Child(Transform p, int size, float y, bool body)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI obj = UiKit.Text("t", p, size, UiKit.Ink, (TextAlignmentOptions)514, body);
			RectTransform rectTransform = ((TMP_Text)obj).rectTransform;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			rectTransform.anchorMax = val;
			rectTransform.anchorMin = val;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.sizeDelta = new Vector2(226f, (float)(size + 10));
			rectTransform.anchoredPosition = new Vector2(0f, y);
			return obj;
		}

		private Image[] MakeBorder(Transform p, float t)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Image val = UiKit.Img("frame", p, UiKit.SoftFrame(), UiKit.Gold, (Type)1);
			val.pixelsPerUnitMultiplier = 0.5f;
			UiKit.Stretch(((Graphic)val).rectTransform);
			((Graphic)val).raycastTarget = false;
			return (Image[])(object)new Image[1] { val };
		}

		private static void Place(RectTransform rt, Vector2 anchor, Vector2 size, Vector2 pos)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			Vector2 anchorMin = (rt.anchorMax = anchor);
			rt.anchorMin = anchorMin;
			rt.pivot = new Vector2(0.5f, 0.5f);
			rt.sizeDelta = size;
			rt.anchoredPosition = pos;
		}

		private void RecomputeHover()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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)
			//IL_0083: Expected O, but got Unknown
			_hoverIdx = -1;
			object obj;
			if (!((Object)(object)_root != (Object)null))
			{
				obj = null;
			}
			else
			{
				Canvas componentInParent = _root.GetComponentInParent<Canvas>();
				obj = ((componentInParent != null) ? componentInParent.worldCamera : null);
			}
			Camera val = (Camera)obj;
			for (int i = 0; i < 3; i++)
			{
				BoonBtn boonBtn = _boons[i];
				if (!((Object)(object)boonBtn?.btn == (Object)null) && ((Component)boonBtn.btn).gameObject.activeInHierarchy && RectTransformUtility.RectangleContainsScreenPoint((RectTransform)((Component)boonBtn.btn).transform, Vector2.op_Implicit(Input.mousePosition), val))
				{
					_hoverIdx = i;
					break;
				}
			}
		}

		private static void AddTrigger(EventTrigger et, EventTriggerType type, Action act)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			Entry val = new Entry
			{
				eventID = type
			};
			((UnityEvent<BaseEventData>)(object)val.callback).AddListener((UnityAction<BaseEventData>)delegate
			{
				act();
			});
			et.triggers.Add(val);
		}

		private void Update()
		{
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: 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)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_04af: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			bool flag = BoonCfg.Enabled && BoonHud.Choosing && BoonHud.Offer != null;
			if (_built && (Object)(object)_root == (Object)null)
			{
				_built = false;
			}
			if (!_built)
			{
				if (!flag)
				{
					return;
				}
				BuildUI();
			}
			_root.SetActive(flag);
			if (flag && !_wasShown)
			{
				_hoverSettle = 4;
			}
			_wasShown = flag;
			if (!flag)
			{
				return;
			}
			if (_hoverSettle > 0)
			{
				_hoverSettle--;
				RecomputeHover();
			}
			string text = (string.IsNullOrEmpty(BoonCfg.ChooserPanelSprite) ? CharSheetCfg.PanelSprite : BoonCfg.ChooserPanelSprite);
			if (_appliedSprite != text)
			{
				_appliedSprite = text;
				if (UiKit.ApplyPanel(_panel, text))
				{
					_basePPU = _panel.pixelsPerUnitMultiplier;
				}
			}
			_panel.pixelsPerUnitMultiplier = _basePPU / Mathf.Max(0.01f, BoonCfg.ChooserPanelZoom);
			List<Boon> offer = BoonHud.Offer;
			for (int i = 0; i < 3; i++)
			{
				BoonBtn boonBtn = _boons[i];
				if (boonBtn == null || (Object)(object)boonBtn.btn == (Object)null)
				{
					continue;
				}
				bool flag2 = i < offer.Count;
				((Component)boonBtn.btn).gameObject.SetActive(flag2);
				if (!flag2)
				{
					continue;
				}
				Boon boon = offer[i];
				int num = Mathf.Clamp(boon.Rarity, 0, RarityCol.Length - 1);
				Color val = RarityCol[num];
				((TMP_Text)boonBtn.rarity).text = RarityName[num].ToUpper();
				((Graphic)boonBtn.rarity).color = val;
				((TMP_Text)boonBtn.name).text = boon.Name;
				((Graphic)boonBtn.name).color = Color.white;
				TextMeshProUGUI val2 = boonBtn.lines[0];
				RectTransform rectTransform = ((TMP_Text)val2).rectTransform;
				if (boon.IsKeystone)
				{
					((Component)val2).gameObject.SetActive(true);
					((TMP_Text)val2).text = boon.Desc;
					((Graphic)val2).color = val;
					((TMP_Text)val2).enableWordWrapping = true;
					((TMP_Text)val2).alignment = (TextAlignmentOptions)258;
					((TMP_Text)val2).outlineWidth = 0f;
					rectTransform.pivot = new Vector2(0.5f, 1f);
					rectTransform.sizeDelta = new Vector2(220f, 72f);
					rectTransform.anchoredPosition = new Vector2(0f, -4f);
					for (int j = 1; j < boonBtn.lines.Length; j++)
					{
						((Component)boonBtn.lines[j]).gameObject.SetActive(false);
					}
				}
				else
				{
					float num2 = -18f;
					int count = boon.Rolls.Count;
					for (int k = 0; k < boonBtn.lines.Length; k++)
					{
						TextMeshProUGUI val3 = boonBtn.lines[k];
						if (k >= count)
						{
							((Component)val3).gameObject.SetActive(false);
							continue;
						}
						RectTransform rectTransform2 = ((TMP_Text)val3).rectTransform;
						((TMP_Text)val3).enableWordWrapping = false;
						((TMP_Text)val3).alignment = (TextAlignmentOptions)514;
						((TMP_Text)val3).outlineWidth = 0f;
						rectTransform2.pivot = new Vector2(0.5f, 0.5f);
						rectTransform2.sizeDelta = new Vector2(226f, 23f);
						((Component)val3).gameObject.SetActive(true);
						((TMP_Text)val3).text = Boon.Line(boon.Rolls[k]);
						((Graphic)val3).color = ((boon.Rolls[k].Net > 0) ? UiKit.Give : UiKit.Take);
						rectTransform2.anchoredPosition = new Vector2(0f, num2);
						num2 -= 22f;
					}
				}
				bool flag3 = _hoverIdx == i;
				if ((Object)(object)boonBtn.bg != (Object)null)
				{
					((Graphic)boonBtn.bg).color = new Color(0.7f, 0.7f, 0.7f);
				}
				if ((Object)(object)boonBtn.hi != (Object)null)
				{
					((Component)boonBtn.hi).gameObject.SetActive(flag3);
				}
				if (boonBtn.border != null)
				{
					Image[] border = boonBtn.border;
					foreach (Image val4 in border)
					{
						if ((Object)(object)val4 != (Object)null)
						{
							((Graphic)val4).color = val;
						}
					}
				}
				if ((Object)(object)boonBtn.halo != (Object)null)
				{
					((Component)boonBtn.halo).gameObject.SetActive(flag3);
					if (flag3)
					{
						float num3 = 0.78f + 0.22f * (0.5f + 0.5f * Mathf.Sin(Time.unscaledTime * 4f));
						((Graphic)boonBtn.halo).color = new Color(val.r, val.g, val.b, num3);
					}
				}
			}
			if ((Object)(object)_rerollLabel != (Object)null)
			{
				((TMP_Text)_rerollLabel).text = $"Reroll ({BoonHud.RerollsLeft})";
			}
			if ((Object)(object)_rerollBtn != (Object)null)
			{
				((Selectable)_rerollBtn).interactable = BoonHud.RerollsLeft > 0;
			}
		}
	}
	internal static class BoonFx
	{
		private static readonly string[] NetTypes = new string[4] { "ZNetView", "ZSyncTransform", "ZSyncAnimation", "TimedDestruction" };

		private static bool _dumped;

		internal static void PlayLevelUp(Player p)
		{
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)p == (Object)null || (Object)(object)ZNetScene.instance == (Object)null || string.IsNullOrEmpty(BoonCfg.LevelUpVfx))
			{
				return;
			}
			bool flag = false;
			string[] array = BoonCfg.LevelUpVfx.Split(';');
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Trim().Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
				if (array2.Length == 0)
				{
					continue;
				}
				string text = array2[0];
				float result = BoonCfg.LevelUpVfxDensity;
				float result2 = 1f;
				float result3 = 1f;
				float result4 = 0f;
				Color? val = null;
				for (int j = 1; j < array2.Length; j++)
				{
					string[] array3 = array2[j].Split('=');
					if (array3.Length != 2)
					{
						continue;
					}
					string text2 = array3[1];
					switch (array3[0].ToLowerInvariant())
					{
					case "density":
						float.TryParse(text2, out result);
						break;
					case "scale":
						float.TryParse(text2, out result2);
						break;
					case "life":
					case "lifetime":
						float.TryParse(text2, out result3);
						break;
					case "delay":
						float.TryParse(text2, out result4);
						break;
					case "tint":
					{
						string[] array4 = text2.Split(',');
						if (array4.Length >= 3 && float.TryParse(array4[0], out var result5) && float.TryParse(array4[1], out var result6) && float.TryParse(array4[2], out var result7))
						{
							val = new Color(result5, result6, result7);
						}
						break;
					}
					}
				}
				if (result4 <= 0f)
				{
					if (SpawnByName(text, result, result2, result3, val))
					{
						flag = true;
					}
					continue;
				}
				string n = text;
				float d = result;
				float s = result2;
				float l = result3;
				Color? t = val;
				Plugin.Scheduler?.RunDelayed(result4, delegate
				{
					SpawnByName(n, d, s, l, t);
				});
				flag = true;
			}
			if (!flag)
			{
				DumpCandidates();
			}
		}

		internal static void PlayUi(bool open)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			InventoryGui instance = InventoryGui.instance;
			if (!((Object)(object)instance == (Object)null))
			{
				EffectList obj = (open ? instance.m_openInventoryEffects : instance.m_closeInventoryEffects);
				Vector3 val = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero);
				if (obj != null)
				{
					obj.Create(val, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				}
			}
		}

		internal static void PlaySound(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null)
			{
				return;
			}
			GameObject prefab = instance.GetPrefab(name);
			if ((Object)(object)prefab == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Pilgrim] pick sfx not found: '" + name + "'"));
				}
			}
			else
			{
				Spawn(prefab, ((Component)localPlayer).transform, 1f, 1f, 1f, null);
			}
		}

		private static bool SpawnByName(string name, float density, float scale, float life, Color? tint)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null)
			{
				return false;
			}
			GameObject prefab = instance.GetPrefab(name);
			if ((Object)(object)prefab == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Pilgrim] level-up VFX not found: '" + name + "'"));
				}
				return false;
			}
			Spawn(prefab, ((Component)localPlayer).transform, density, scale, life, tint);
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)string.Format("[Pilgrim] level-up VFX: {0} density={1} scale={2} life={3} tint={4}", name, density, scale, life, tint.HasValue ? ((object)tint.Value/*cast due to .constrained prefix*/).ToString() : "none"));
			}
			return true;
		}

		private static void DumpCandidates()
		{
			if (_dumped)
			{
				return;
			}
			_dumped = true;
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			string[] keys = new string[14]
			{
				"transform", "frost", "found", "adrenaline", "aspect", "wishbone", "skill", "activat", "lvl", "upgrade",
				"guardian", "spawn", "glow", "burst"
			};
			List<string> list = (from n in (from g in instance.m_prefabs
					where (Object)(object)g != (Object)null
					select ((Object)g).name).Where(delegate(string n)
				{
					string text = n.ToLowerInvariant();
					return text.StartsWith("vfx") || text.StartsWith("fx");
				})
				where keys.Any((string k) => n.ToLowerInvariant().Contains(k))
				orderby n
				select n).Take(80).ToList();
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)string.Format("[Pilgrim] no level-up VFX resolved. Candidate prefabs ({0}): {1}", list.Count, string.Join(", ", list)));
			}
		}

		internal static List<string> ListVfx(string kw)
		{
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return new List<string>();
			}
			kw = (kw ?? "").ToLowerInvariant();
			return (from n in (from g in instance.m_prefabs
					where (Object)(object)g != (Object)null
					select ((Object)g).name).Where(delegate(string n)
				{
					string text = n.ToLowerInvariant();
					return (text.StartsWith("vfx") || text.StartsWith("fx") || text.StartsWith("sfx")) && (kw.Length == 0 || text.Contains(kw));
				})
				orderby n
				select n).ToList();
		}

		internal static string Preview(string name)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return "no player";
			}
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return "scene not ready";
			}
			GameObject prefab = instance.GetPrefab(name);
			if ((Object)(object)prefab == (Object)null)
			{
				return "not found: '" + name + "'";
			}
			Spawn(prefab, ((Component)localPlayer).transform, BoonCfg.LevelUpVfxDensity, 1f, 1f, null);
			return $"spawned '{name}' (density {BoonCfg.LevelUpVfxDensity})";
		}

		internal static string PreviewTuned(string name, float scale, float density, float lifetime, Color? tint)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return "no player";
			}
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return "scene not ready";
			}
			GameObject prefab = instance.GetPrefab(name);
			if ((Object)(object)prefab == (Object)null)
			{
				return "not found: '" + name + "'";
			}
			Spawn(prefab, ((Component)localPlayer).transform, density, scale, lifetime, tint);
			return string.Format("spawned '{0}'  scale={1}  density={2}  lifetime={3}  tint={4}", name, scale, density, lifetime, tint.HasValue ? ((object)tint.Value/*cast due to .constrained prefix*/).ToString() : "none");
		}

		private static void Spawn(GameObject prefab, Transform follow, float density, float scale, float lifetime, Color? tint)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			prefab.SetActive(false);
			GameObject val = Object.Instantiate<GameObject>(prefab, follow.position + Vector3.up * 0.5f, follow.rotation);
			prefab.SetActive(true);
			MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val2 in componentsInChildren)
			{
				if ((Object)(object)val2 != (Object)null && Array.IndexOf(NetTypes, ((object)val2).GetType().Name) >= 0)
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
			}
			ParticleSystem[] componentsInChildren2 = val.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val3 in componentsInChildren2)
			{
				if (Mathf.Abs(density - 1f) > 0.001f)
				{
					ScaleDensity(val3, density);
				}
				MainModule main = val3.main;
				if (tint.HasValue)
				{
					((MainModule)(ref main)).startColor = new MinMaxGradient(tint.Value);
				}
				if (Mathf.Abs(lifetime - 1f) > 0.001f)
				{
					MinMaxCurve startLifetime = ((MainModule)(ref main)).startLifetime;
					((MinMaxCurve)(ref startLifetime)).constant = ((MinMaxCurve)(ref startLifetime)).constant * lifetime;
					((MinMaxCurve)(ref startLifetime)).constantMin = ((MinMaxCurve)(ref startLifetime)).constantMin * lifetime;
					((MinMaxCurve)(ref startLifetime)).constantMax = ((MinMaxCurve)(ref startLifetime)).constantMax * lifetime;
					((MainModule)(ref main)).startLifetime = startLifetime;
				}
			}
			if (Mathf.Abs(scale - 1f) > 0.001f)
			{
				val.transform.localScale = Vector3.one * scale;
			}
			val.transform.SetParent(follow, true);
			val.SetActive(true);
			Object.Destroy((Object)(object)val, 8f);
		}

		internal static void ScaleDensity(GameObject go, float m)
		{
			ParticleSystem[] componentsInChildren = go.GetComponentsInChildren<ParticleSystem>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				ScaleDensity(componentsInChildren[i], m);
			}
		}

		private static void ScaleDensity(ParticleSystem ps, float m)
		{
			//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)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			EmissionModule emission = ps.emission;
			MinMaxCurve rateOverTime = ((EmissionModule)(ref emission)).rateOverTime;
			((MinMaxCurve)(ref rateOverTime)).constant = ((MinMaxCurve)(ref rateOverTime)).constant * m;
			((MinMaxCurve)(ref rateOverTime)).constantMin = ((MinMaxCurve)(ref rateOverTime)).constantMin * m;
			((MinMaxCurve)(ref rateOverTime)).constantMax = ((MinMaxCurve)(ref rateOverTime)).constantMax * m;
			((EmissionModule)(ref emission)).rateOverTime = rateOverTime;
			int burstCount = ((EmissionModule)(ref emission)).burstCount;
			if (burstCount > 0)
			{
				Burst[] array = (Burst[])(object)new Burst[burstCount];
				((EmissionModule)(ref emission)).GetBursts(array);
				for (int i = 0; i < burstCount; i++)
				{
					MinMaxCurve count = ((Burst)(ref array[i])).count;
					((MinMaxCurve)(ref count)).constant = ((MinMaxCurve)(ref count)).constant * m;
					((MinMaxCurve)(ref count)).constantMin = ((MinMaxCurve)(ref count)).constantMin * m;
					((MinMaxCurve)(ref count)).constantMax = ((MinMaxCurve)(ref count)).constantMax * m;
					((Burst)(ref array[i])).count = count;
				}
				((EmissionModule)(ref emission)).SetBursts(array);
			}
			MainModule main = ps.main;
			((MainModule)(ref main)).maxParticles = Mathf.CeilToInt((float)((MainModule)(ref main)).maxParticles * Mathf.Max(1f, m));
		}
	}
	internal sealed class BoonHudUI : MonoBehaviour
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<TMP_FontAsset, bool> <>9__19_0;

			public static Func<TMP_FontAsset, bool> <>9__19_1;

			public static UnityAction <>9__25_0;

			internal bool <FindFont>b__19_0(TMP_FontAsset f)
			{
				return ((Object)f).name.Contains("Norse");
			}

			internal bool <FindFont>b__19_1(TMP_FontAsset f)
			{
				return ((Object)f).name.Contains("Averia");
			}

			internal void <Build>b__25_0()
			{
				BoonHud.ToggleDraw();
			}
		}

		private static BoonHudUI _inst;

		private Canvas _canvas;

		private TMP_FontAsset _font;

		private Sprite _white;

		private Sprite _grad;

		private Sprite _diamond;

		private RectTransform _barBg;

		private Image _barFill;

		private RectTransform _iconRt;

		private Image _iconImg;

		private Image _ringImg;

		private RectTransform _ringRt;

		private TextMeshProUGUI _iconTxt;

		private TextMeshProUGUI _count;

		private bool _built;

		private static readonly Color Gold = new Color(0.9f, 0.75f, 0.4f);

		private static readonly Color GoldHi = new Color(1f, 0.92f, 0.6f);

		private static readonly Color Muted = new Color(0.62f, 0.54f, 0.36f);

		internal static void Ensure()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)_inst != (Object)null))
			{
				GameObject val = new GameObject("PilgrimBoonCanvas");
				Object.DontDestroyOnLoad((Object)val);
				_inst = val.AddComponent<BoonHudUI>();
			}
		}

		private TMP_FontAsset FindFont()
		{
			TMP_FontAsset[] source = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
			return ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.Contains("Norse"))) ?? ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.Contains("Averia"))) ?? source.FirstOrDefault();
		}

		private static Sprite SolidSprite(Color c)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			Color[] array = (Color[])(object)new Color[4];
			for (int i = 0; i < 4; i++)
			{
				array[i] = c;
			}
			val.SetPixels(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 2f, 2f), new Vector2(0.5f, 0.5f));
		}

		private static Sprite GradSprite()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_004c: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(64, 1, (TextureFormat)4, false)
			{
				wrapMode = (TextureWrapMode)1,
				filterMode = (FilterMode)1
			};
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.98f, 0.86f, 0.46f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.52f, 0.38f, 0.14f);
			for (int i = 0; i < 64; i++)
			{
				val.SetPixel(i, 0, Color.Lerp(val2, val3, (float)i / 63f));
			}
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 1f), new Vector2(0.5f, 0.5f));
		}

		private static Sprite DiamondSprite(int size = 48)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			float num = (float)(size - 1) / 2f;
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.96f, 0.84f, 0.46f, 1f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.28f, 0.21f, 0.09f, 1f);
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num2 = (Mathf.Abs((float)j - num) + Mathf.Abs((float)i - num)) / num;
					Color val4 = (Color)((num2 > 1f) ? new Color(0f, 0f, 0f, 0f) : ((num2 > 0.78f) ? val2 : val3));
					val.SetPixel(j, i, val4);
				}
			}
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f));
		}

		private Image NewImage(string name, Transform parent, Sprite spr, Color col, bool filled = false)
		{
			//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_004e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			Image component = val.GetComponent<Image>();
			component.sprite = spr;
			((Graphic)component).color = col;
			((Graphic)component).raycastTarget = false;
			if (filled)
			{
				component.type = (Type)3;
				component.fillMethod = (FillMethod)1;
				component.fillOrigin = 0;
			}
			return component;
		}

		private TextMeshProUGUI NewText(string name, Transform parent, int size, Color col)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)obj).font = _font;
			((TMP_Text)obj).fontSize = size;
			((Graphic)obj).color = col;
			((TMP_Text)obj).alignment = (TextAlignmentOptions)514;
			((Graphic)obj).raycastTarget = false;
			return obj;
		}

		private void Build()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: 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_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Unknown result type (might be due to invalid IL or missing references)
			//IL_046e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Expected O, but got Unknown
			_font = FindFont();
			_white = SolidSprite(Color.white);
			_grad = GradSprite();
			_diamond = DiamondSprite();
			GameObject val = new GameObject("Canvas", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(((Component)this).transform, false);
			_canvas = val.AddComponent<Canvas>();
			_canvas.renderMode = (RenderMode)0;
			_canvas.sortingOrder = 5000;
			CanvasScaler obj = val.AddComponent<CanvasScaler>();
			obj.uiScaleMode = (ScaleMode)0;
			obj.scaleFactor = 1f;
			val.AddComponent<GraphicRaycaster>();
			Transform transform = val.transform;
			_barBg = ((Graphic)NewImage("XpTrack", transform, _white, new Color(0f, 0f, 0f, 0.85f))).rectTransform;
			_barBg.pivot = new Vector2(0f, 0f);
			RectTransform barBg = _barBg;
			RectTransform barBg2 = _barBg;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0f, 0f);
			barBg2.anchorMax = val2;
			barBg.anchorMin = val2;
			_barFill = NewImage("XpFill", (Transform)(object)_barBg, _grad, Color.white, filled: true);
			RectTransform rectTransform = ((Graphic)_barFill).rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = Vector2.one;
			rectTransform.offsetMin = Vector2.zero;
			rectTransform.offsetMax = Vector2.zero;
			for (int i = 1; i < 4; i++)
			{
				RectTransform rectTransform2 = ((Graphic)NewImage($"Tick{i}", (Transform)(object)_barBg, _white, new Color(0f, 0f, 0f, 0.5f))).rectTransform;
				rectTransform2.anchorMin = new Vector2(0f, (float)i / 4f);
				rectTransform2.anchorMax = new Vector2(1f, (float)i / 4f);
				rectTransform2.pivot = new Vector2(0.5f, 0.5f);
				rectTransform2.sizeDelta = new Vector2(0f, 1f);
				rectTransform2.anchoredPosition = Vector2.zero;
			}
			_ringImg = NewImage("XpRing", transform, _diamond, new Color(1f, 1f, 1f, 0f));
			_ringRt = ((Graphic)_ringImg).rectTransform;
			_ringRt.pivot = new Vector2(0.5f, 0.5f);
			RectTransform ringRt = _ringRt;
			RectTransform ringRt2 = _ringRt;
			((Vector2)(ref val2))..ctor(0f, 0f);
			ringRt2.anchorMax = val2;
			ringRt.anchorMin = val2;
			((Component)_ringImg).gameObject.SetActive(false);
			_iconImg = NewImage("XpIcon", transform, _diamond, Muted);
			((Graphic)_iconImg).raycastTarget = true;
			Button obj2 = ((Component)_iconImg).gameObject.AddComponent<Button>();
			((Selectable)obj2).transition = (Transition)0;
			ButtonClickedEvent onClick = obj2.onClick;
			object obj3 = <>c.<>9__25_0;
			if (obj3 == null)
			{
				UnityAction val3 = delegate
				{
					BoonHud.ToggleDraw();
				};
				<>c.<>9__25_0 = val3;
				obj3 = (object)val3;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj3);
			_iconRt = ((Graphic)_iconImg).rectTransform;
			_iconRt.pivot = new Vector2(0.5f, 0.5f);
			RectTransform iconRt = _iconRt;
			RectTransform iconRt2 = _iconRt;
			((Vector2)(ref val2))..ctor(0f, 0f);
			iconRt2.anchorMax = val2;
			iconRt.anchorMin = val2;
			_iconTxt = NewText("XpLabel", (Transform)(object)_iconRt, 14, new Color(0.14f, 0.1f, 0.04f));
			((TMP_Text)_iconTxt).text = "XP";
			((TMP_Text)_iconTxt).fontStyle = (FontStyles)1;
			RectTransform rectTransform3 = ((TMP_Text)_iconTxt).rectTransform;
			rectTransform3.anchorMin = Vector2.zero;
			rectTransform3.anchorMax = Vector2.one;
			rectTransform3.offsetMin = Vector2.zero;
			rectTransform3.offsetMax = Vector2.zero;
			_count = NewText("XpCount", transform, 12, GoldHi);
			((TMP_Text)_count).rectTransform.pivot = new Vector2(0f, 0.5f);
			RectTransform rectTransform4 = ((TMP_Text)_count).rectTransform;
			RectTransform rectTransform5 = ((TMP_Text)_count).rectTransform;
			((Vector2)(ref val2))..ctor(0f, 0f);
			rectTransform5.anchorMax = val2;
			rectTransform4.anchorMin = val2;
			_built = true;
		}

		private bool FoodRect(out float left, out float bottom, out float h)
		{
			left = (bottom = (h = 0f));
			RectTransform val = Hud.instance?.m_foodBarRoot;
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			val.GetWorldCorners(array);
			left = array[0].x;
			bottom = array[0].y;
			h = array[1].y - array[0].y;
			return h > 1f;
		}

		private void Update()
		{
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0425: Unknown result type (might be due to invalid IL or missing references)
			//IL_0432: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0488: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			BoonState state = BoonHud.State;
			Player localPlayer = Player.m_localPlayer;
			bool flag = (Object)(object)Hud.instance != (Object)null && (Object)(object)Hud.instance.m_rootObject != (Object)null && Hud.instance.m_rootObject.activeInHierarchy;
			bool flag2 = BoonCfg.Enabled && (Object)(object)localPlayer != (Object)null && state != null && flag && !((Character)localPlayer).IsTeleporting();
			if (!_built)
			{
				if (!flag2)
				{
					return;
				}
				Build();
			}
			((Component)_canvas).gameObject.SetActive(flag2);
			if (!flag2)
			{
				return;
			}
			float xpBarWidth = BoonCfg.XpBarWidth;
			float num = 6f;
			if (!FoodRect(out var left, out var bottom, out var h))
			{
				h = 120f;
				left = 80f;
				bottom = 80f;
			}
			float num2 = Mathf.Clamp(h * 0.26f * 1.4f, 36f, 56f);
			float num3 = left - xpBarWidth - num - num2 * 0.9f + BoonCfg.XpBarNudgeX;
			float num4 = bottom + num2 * 0.55f + BoonCfg.XpBarNudgeY;
			_barBg.anchoredPosition = new Vector2(num3, num4);
			_barBg.sizeDelta = new Vector2(xpBarWidth, h);
			_barFill.fillAmount = Mathf.Clamp01((float)state.Xp / (float)BoonCfg.NeedForNext(state.Level));
			_iconRt.sizeDelta = new Vector2(num2, num2);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(num3 + xpBarWidth / 2f, num4 - num2 / 2f - 6f);
			bool flag3 = state.Pending > 0;
			float unscaledTime = Time.unscaledTime;
			float num5 = Mathf.PingPong(unscaledTime * 1.6f, 1f);
			Color color = (flag3 ? Color.Lerp(Gold, GoldHi, num5) : Gold);
			((Transform)_iconRt).localScale = Vector3.one;
			((Transform)_iconRt).localRotation = Quaternion.identity;
			bool flag4 = false;
			if (flag3)
			{
				switch ((BoonCfg.BoonAlert ?? "pulse").ToLowerInvariant())
				{
				case "throb":
					((Transform)_iconRt).localScale = Vector3.one * (1f + 0.22f * num5);
					break;
				case "bob":
					val += new Vector2(0f, Mathf.Sin(unscaledTime * 5f) * 6f);
					((Transform)_iconRt).localScale = Vector3.one * (1f + 0.07f * num5);
					break;
				case "spin":
					((Transform)_iconRt).localRotation = Quaternion.Euler(0f, 0f, Mathf.Sin(unscaledTime * 4f) * 20f);
					((Transform)_iconRt).localScale = Vector3.one * (1f + 0.07f * num5);
					break;
				case "shake":
					val += new Vector2(Mathf.Sin(unscaledTime * 40f) * 2f, 0f);
					break;
				case "ping":
					flag4 = true;
					((Transform)_iconRt).localScale = Vector3.one * (1f + 0.05f * num5);
					break;
				default:
					((Transform)_iconRt).localScale = Vector3.one * (1f + 0.07f * num5);
					break;
				}
			}
			_iconRt.anchoredPosition = val;
			((Graphic)_iconImg).color = color;
			((Graphic)_iconTxt).color = color;
			((TMP_Text)_iconTxt).text = (flag3 ? state.Pending.ToString() : "XP");
			((Component)_count).gameObject.SetActive(false);
			if (flag4)
			{
				float num6 = unscaledTime * 1.2f % 1f;
				((Component)_ringImg).gameObject.SetActive(true);
				_ringRt.anchoredPosition = val;
				_ringRt.sizeDelta = Vector2.one * num2 * (1f + num6 * 1.2f);
				((Graphic)_ringImg).color = new Color(GoldHi.r, GoldHi.g, GoldHi.b, (1f - num6) * 0.55f);
			}
			else if (((Component)_ringImg).gameObject.activeSelf)
			{
				((Component)_ringImg).gameObject.SetActive(false);
			}
		}
	}
	internal static class BoonCfg
	{
		private static readonly BoonsConfig _fb = new BoonsConfig();

		private static BoonsConfig C => Plugin.Cfg?.Boons ?? _fb;

		internal static bool Enabled => C.Enabled;

		internal static int XpPerKill => C.XpPerKill;

		internal static float XpHealthRef => C.XpHealthRef;

		internal static int DrawCount => C.DrawCount;

		internal static int Rerolls => C.Rerolls;

		internal static string LevelUpVfx => C.LevelUpVfx;

		internal static float LevelUpVfxDensity => C.LevelUpVfxDensity;

		internal static string PickSfx => C.PickSfx;

		internal static string ToggleSfx => C.ToggleSfx;

		internal static string ChooserCardSprite => C.ChooserCardSprite;

		internal static string ChooserPanelSprite => C.ChooserPanelSprite;

		internal static float ChooserPanelZoom => C.ChooserPanelZoom;

		internal static string BoonAlert => C.BoonAlert;

		internal static float XpBarWidth => C.XpBarWidth;

		internal static float XpBarNudgeX => C.XpBarNudgeX;

		internal static float XpBarNudgeY => C.XpBarNudgeY;

		internal static float LegendaryChance => C.LegendaryChance;

		internal static float AttrW1 => C.AttrW1;

		internal static float AttrW2 => C.AttrW2;

		internal static float AttrW3 => C.AttrW3;

		internal static float AttrW4 => C.AttrW4;

		internal static float WeightGeneral => C.WeightGeneral;

		internal static float WeightResist => C.WeightResist;

		internal static float WeightDmgType => C.WeightDmgType;

		internal static float WeightStamLeaf => C.WeightStamLeaf;

		internal static float WeightBase => C.WeightBase;

		internal static float PyrrhicBaseFactor => C.PyrrhicBaseFactor;

		internal static void EnsureBound()
		{
		}

		internal static bool LegendaryEnabled(KeystoneId id)
		{
			return id switch
			{
				KeystoneId.Grief => C.GriefEnabled, 
				KeystoneId.Grace => C.GraceEnabled, 
				KeystoneId.Conviction => C.ConvictionEnabled, 
				KeystoneId.Sonder => C.SonderEnabled, 
				KeystoneId.Dread => C.DreadEnabled, 
				KeystoneId.Avarice => C.AvariceEnabled, 
				KeystoneId.Regret => C.RegretEnabled, 
				KeystoneId.Resent => C.ResentEnabled, 
				KeystoneId.Wrath => C.WrathEnabled, 
				KeystoneId.Betrayal => C.BetrayalEnabled, 
				KeystoneId.Panic => C.PanicEnabled, 
				KeystoneId.Nostalgia => C.NostalgiaEnabled, 
				KeystoneId.Temerity => C.TemerityEnabled, 
				KeystoneId.Contempt => C.ContemptEnabled, 
				KeystoneId.Pyrrhic => C.PyrrhicEnabled, 
				_ => true, 
			};
		}

		internal static int NeedForNext(int level)
		{
			return Mathf.Max(1, Mathf.RoundToInt(C.XpCurveBase * Mathf.Pow(C.XpCurveGrowth, (float)level)));
		}
	}
	internal enum KeystoneId
	{
		None,
		Grief,
		Grace,
		Conviction,
		Sonder,
		Dread,
		Avarice,
		Regret,
		Resent,
		Wrath,
		Betrayal,
		Panic,
		Nostalgia,
		Temerity,
		Contempt,
		Pyrrhic
	}
	internal sealed class KeystoneDef
	{
		public KeystoneId Id;

		public string Name;

		public string Desc;

		public string Sheet;
	}
	internal static class Keystones
	{
		internal static readonly Dictionary<KeystoneId, KeystoneDef> Def = new Dictionary<KeystoneId, KeystoneDef>
		{
			[KeystoneId.Grief] = new KeystoneDef
			{
				Id = KeystoneId.Grief,
				Name = "Grief",
				Desc = "You are the wound that never heals",
				Sheet = "Damage you inflict cannot be healed"
			},
			[KeystoneId.Grace] = new KeystoneDef
			{
				Id = KeystoneId.Grace,
				Name = "Grace",
				Desc = "You are the gasp of a dying breath",
				Sheet = "A mortal blow leaves you at 1 HP, once per minute"
			},
			[KeystoneId.Conviction] = new KeystoneDef
			{
				Id = KeystoneId.Conviction,
				Name = "Conviction",
				Desc = "You are the shield that never yields",
				Sheet = "Cannot be staggered while blocking with a shield"
			},
			[KeystoneId.Sonder] = new KeystoneDef
			{
				Id = KeystoneId.Sonder,
				Name = "Sonder",
				Desc = "You are the wisdom of perspective",
				Sheet = "Grants triple experience"
			},
			[KeystoneId.Dread] = new KeystoneDef
			{
				Id = KeystoneId.Dread,
				Name = "Dread",
				Desc = "You are the premonition of danger",
				Sheet = "Grants sneak +30"
			},
			[KeystoneId.Avarice] = new KeystoneDef
			{
				Id = KeystoneId.Avarice,
				Name = "Avarice",
				Desc = "You are the hand in every pocket",
				Sheet = "Grants 3x treasure"
			},
			[KeystoneId.Regret] = new KeystoneDef
			{
				Id = KeystoneId.Regret,
				Name = "Regret",
				Desc = "You'll bear anything but the weight of what you did",
				Sheet = "Grants 2x carry weight"
			},
			[KeystoneId.Resent] = new KeystoneDef
			{
				Id = KeystoneId.Resent,
				Name = "Resent",
				Desc = "You lash out and don't remember why anymore",
				Sheet = "Excess block force is reflected to the attacker"
			},
			[KeystoneId.Wrath] = new KeystoneDef
			{
				Id = KeystoneId.Wrath,
				Name = "Wrath",
				Desc = "Your anger shall not be mitigated",
				Sheet = "Grants 2x slash damage"
			},
			[KeystoneId.Betrayal] = new KeystoneDef
			{
				Id = KeystoneId.Betrayal,
				Name = "Betrayal",
				Desc = "You let them put their trust in you",
				Sheet = "Grants 10x backstab damage with knives"
			},
			[KeystoneId.Panic] = new KeystoneDef
			{
				Id = KeystoneId.Panic,
				Name = "Panic",
				Desc = "Your hands tremble with intent",
				Sheet = "Bow draws in 25% the time"
			},
			[KeystoneId.Nostalgia] = new KeystoneDef
			{
				Id = KeystoneId.Nostalgia,
				Name = "Nostalgia",
				Desc = "You long for the fellowship of youth",
				Sheet = "Foods last 20% longer"
			},
			[KeystoneId.Temerity] = new KeystoneDef
			{
				Id = KeystoneId.Temerity,
				Name = "Temerity",
				Desc = "You ignore the warnings of danger",
				Sheet = "Grants 2x blunt damage"
			},
			[KeystoneId.Contempt] = new KeystoneDef
			{
				Id = KeystoneId.Contempt,
				Name = "Contempt",
				Desc = "Your voice is hatred transcending diction",
				Sheet = "Grants 2x pierce damage"
			},
			[KeystoneId.Pyrrhic] = new KeystoneDef
			{
				Id = KeystoneId.Pyrrhic,
				Name = "Pyrrhic",
				Desc = "You'll stand at the table while blood fills your shoes",
				Sheet = "Grants favorable boon rolls"
			}
		};

		internal static readonly KeystoneId[] All = Def.Keys.ToArray();

		internal static bool Available(KeystoneId id)
		{
			if (Def.ContainsKey(id))
			{
				return BoonCfg.LegendaryEnabled(id);
			}
			return false;
		}
	}
	internal enum BoonAxis
	{
		Damage,
		AtkStamina,
		MoveSpeed,
		HpRegen,
		StamRegen,
		FlatArmor,
		RunStamina,
		JumpStamina,
		BlockStamina,
		DodgeStamina,
		SwimStamina,
		SneakStamina,
		Stagger,
		FallDamage,
		ArmorPct,
		Parry,
		EitrRegen,
		SwimSpeed,
		Stealth,
		CarryWeight,
		BuildStamina,
		StaminaUse,
		Defense,
		ResBlunt,
		ResSlash,
		ResPierce,
		ResFire,
		ResFrost,
		ResPoison,
		ResLightning,
		ResSpirit,
		DmgBlunt,
		DmgSlash,
		DmgPierce,
		DmgFire,
		DmgFrost,
		DmgPoison,
		DmgLightning,
		DmgSpirit,
		SkillXp,
		AttackSpeed,
		StaggerDealt,
		BackstabDealt,
		CrouchSpeed,
		JumpHeight,
		Survival,
		WoodCutting,
		Pickaxes,
		FoodDuration,
		RestedDuration,
		BlockForce
	}
	internal sealed class AxisDef
	{
		public string GiveAdj;

		public string GiveNoun;

		public string TakeAdj;

		public string TakeNoun;

		public string Noun;

		public bool Percent;

		public bool Cost;

		public bool General;

		public bool Categorical;

		public DamageType DType;
	}
	internal static class Axes
	{
		internal static readonly Dictionary<BoonAxis, AxisDef> Def = new Dictionary<BoonAxis, AxisDef>
		{
			[BoonAxis.Damage] = new AxisDef
			{
				GiveAdj = "Keen",
				GiveNoun = "the Edge",
				TakeAdj = "Dull",
				TakeNoun = "the Dull",
				Noun = "damage",
				Percent = true,
				General = true
			},
			[BoonAxis.AtkStamina] = new AxisDef
			{
				GiveAdj = "Deft",
				GiveNoun = "the Flurry",
				TakeAdj = "Taxing",
				TakeNoun = "the Exertion",
				Noun = "attack stamina use",
				Percent = true,
				Cost = true
			},
			[BoonAxis.MoveSpeed] = new AxisDef
			{
				GiveAdj = "Swift",
				GiveNoun = "Haste",
				TakeAdj = "Sluggish",
				TakeNoun = "Sloth",
				Noun = "move speed",
				Percent = true
			},
			[BoonAxis.HpRegen] = new AxisDef
			{
				GiveAdj = "Mending",
				GiveNoun = "Recovery",
				TakeAdj = "Festering",
				TakeNoun = "the Wound",
				Noun = "health regen",
				Percent = true
			},
			[BoonAxis.StamRegen] = new AxisDef
			{
				GiveAdj = "Tireless",
				GiveNoun = "Endurance",
				TakeAdj = "Weary",
				TakeNoun = "Weariness",
				Noun = "stamina regen",
				Percent = true
			},
			[BoonAxis.FlatArmor] = new AxisDef
			{
				GiveAdj = "Warded",
				GiveNoun = "the Bulwark",
				TakeAdj = "Brittle",
				TakeNoun = "Brittleness",
				Noun = "armor",
				Percent = false
			},
			[BoonAxis.RunStamina] = new AxisDef
			{
				GiveAdj = "Bounding",
				GiveNoun = "Vigor",
				TakeAdj = "Heavy",
				TakeNoun = "the Burden",
				Noun = "run stamina use",
				Percent = true,
				Cost = true
			},
			[BoonAxis.JumpStamina] = new AxisDef
			{
				GiveAdj = "Lofty",
				GiveNoun = "the Spring",
				TakeAdj = "Leaden",
				TakeNoun = "the Anchor",
				Noun = "jump stamina use",
				Percent = true,
				Cost = true
			},
			[BoonAxis.BlockStamina] = new AxisDef
			{
				GiveAdj = "Steady",
				GiveNoun = "the Guard",
				TakeAdj = "Strained",
				TakeNoun = "the Strain",
				Noun = "block stamina use",
				Percent = true,
				Cost = true
			},
			[BoonAxis.DodgeStamina] = new AxisDef
			{
				GiveAdj = "Nimble",
				GiveNoun = "Evasion",
				TakeAdj = "Clumsy",
				TakeNoun = "Clumsiness",
				Noun = "dodge stamina use",
				Percent = true,
				Cost = true
			},
			[BoonAxis.SwimStamina] = new AxisDef
			{
				GiveAdj = "Buoyant",
				GiveNoun = "the Tide",
				TakeAdj = "Sinking",
				TakeNoun = "the Depths",
				Noun = "swim stamina use",
				Percent = true,
				Cost = true
			},
			[BoonAxis.SneakStamina] = new AxisDef
			{
				GiveAdj = "Quiet",
				GiveNoun = "Stillness",
				TakeAdj = "Restless",
				TakeNoun = "Restlessness",
				Noun = "sneak stamina use",
				Percent = true,
				Cost = true
			},
			[BoonAxis.Stagger] = new AxisDef
			{
				GiveAdj = "Unshaken",
				GiveNoun = "Poise",
				TakeAdj = "Faltering",
				TakeNoun = "the Falter",
				Noun = "stagger",
				Percent = true,
				Cost = true
			},
			[BoonAxis.FallDamage] = new AxisDef
			{
				GiveAdj = "Feathered",
				GiveNoun = "the Feather",
				TakeAdj = "Plummeting",
				TakeNoun = "the Plummet",
				Noun = "fall damage",
				Percent = true,
				Cost = true
			},
			[BoonAxis.ArmorPct] = new AxisDef
			{
				GiveAdj = "Ironclad",
				GiveNoun = "the Aegis",
				TakeAdj = "Exposed",
				TakeNoun = "Exposure",
				Noun = "armor",
				Percent = true
			},
			[BoonAxis.Parry] = new AxisDef
			{
				GiveAdj = "Deflecting",
				GiveNoun = "the Parry",
				TakeAdj = "Open",
				TakeNoun = "the Opening",
				Noun = "parry bonus",
				Percent = true
			},
			[BoonAxis.EitrRegen] = new AxisDef
			{
				GiveAdj = "Attuned",
				GiveNoun = "the Flow",
				TakeAdj = "Dim",
				TakeNoun = "the Dimming",
				Noun = "eitr regen",
				Percent = true
			},
			[BoonAxis.SwimSpeed] = new AxisDef
			{
				GiveAdj = "Gliding",
				GiveNoun = "the Current",
				TakeAdj = "Dragging",
				TakeNoun = "the Drag",
				Noun = "swim speed",
				Percent = true
			},
			[BoonAxis.Stealth] = new AxisDef
			{
				GiveAdj = "Unseen",
				GiveNoun = "the Veil",
				TakeAdj = "Conspicuous",
				TakeNoun = "the Glare",
				Noun = "sneak",
				Percent = false
			},
			[BoonAxis.CarryWeight] = new AxisDef
			{
				GiveAdj = "Mighty",
				GiveNoun = "the Ox",
				TakeAdj = "Overladen",
				TakeNoun = "the Load",
				Noun = "carry weight",
				Percent = false
			},
			[BoonAxis.BuildStamina] = new AxisDef
			{
				GiveAdj = "Industrious",
				GiveNoun = "the Craft",
				TakeAdj = "Toilsome",
				TakeNoun = "the Labor",
				Noun = "build stamina use",
				Percent = true,
				Cost = true
			},
			[BoonAxis.StaminaUse] = new AxisDef
			{
				GiveAdj = "Fluid",
				GiveNoun = "Grace",
				TakeAdj = "Labored",
				TakeNoun = "Toil",
				Noun = "stamina use",
				Percent = true,
				Cost = true,
				General = true
			},
			[BoonAxis.Defense] = new AxisDef
			{
				GiveAdj = "Stalwart",
				GiveNoun = "the Wall",
				TakeAdj = "Vulnerable",
				TakeNoun = "the Breach",
				Noun = "defense",
				Percent = true,
				General = true
			},
			[BoonAxis.ResBlunt] = new AxisDef
			{
				GiveAdj = "Padded",
				GiveNoun = "the Cushion",
				TakeAdj = "Bruised",
				TakeNoun = "the Bruise",
				Noun = "blunt",
				Categorical = true,
				DType = (DamageType)1
			},
			[BoonAxis.ResSlash] = new AxisDef
			{
				GiveAdj = "Toughhide",
				GiveNoun = "the Hide",
				TakeAdj = "Lacerated",
				TakeNoun = "the Gash",
				Noun = "slash",
				Categorical = true,
				DType = (DamageType)2
			},
			[BoonAxis.ResPierce] = new AxisDef
			{
				GiveAdj = "Plated",
				GiveNoun = "the Plate",
				TakeAdj = "Punctured",
				TakeNoun = "the Puncture",
				Noun = "pierce",
				Categorical = true,
				DType = (DamageType)4
			},
			[BoonAxis.ResFire] = new AxisDef
			{
				GiveAdj = "Fireproof",
				GiveNoun = "the Ember",
				TakeAdj = "Scorched",
				TakeNoun = "the Pyre",
				Noun = "fire",
				Categorical = true,
				DType = (DamageType)32
			},
			[BoonAxis.ResFrost] = new AxisDef
			{
				GiveAdj = "Frostward",
				GiveNoun = "the Thaw",
				TakeAdj = "Chilled",
				TakeNoun = "the Frost",
				Noun = "frost",
				Categorical = true,
				DType = (DamageType)64
			},
			[BoonAxis.ResPoison] = new AxisDef
			{
				GiveAdj = "Purified",
				GiveNoun = "the Antidote",
				TakeAdj = "Envenomed",
				TakeNoun = "the Venom",
				Noun = "poison",
				Categorical = true,
				DType = (DamageType)256
			},
			[BoonAxis.ResLightning] = new AxisDef
			{
				GiveAdj = "Grounded",
				GiveNoun = "the Earth",
				TakeAdj = "Shocked",
				TakeNoun = "the Storm",
				Noun = "lightning",
				Categorical = true,
				DType = (DamageType)128
			},
			[BoonAxis.ResSpirit] = new AxisDef
			{
				GiveAdj = "Hallowed",
				GiveNoun = "the Ward",
				TakeAdj = "Haunted",
				TakeNoun = "the Specter",
				Noun = "spirit",
				Categorical = true,
				DType = (DamageType)512
			},
			[BoonAxis.DmgBlunt] = new AxisDef
			{
				GiveAdj = "Crushing",
				GiveNoun = "the Maul",
				TakeAdj = "Soft",
				TakeNoun = "the Softness",
				Noun = "blunt damage",
				Percent = true,
				DType = (DamageType)1
			},
			[BoonAxis.DmgSlash] = new AxisDef
			{
				GiveAdj = "Honed",
				GiveNoun = "the Cut",
				TakeAdj = "Blunted",
				TakeNoun = "the Nick",
				Noun = "slash damage",
				Percent = true,
				DType = (DamageType)2
			},
			[BoonAxis.DmgPierce] = new AxisDef
			{
				GiveAdj = "Piercing",
				GiveNoun = "the Point",
				TakeAdj = "Bent",
				TakeNoun = "the Bend",
				Noun = "pierce damage",
				Percent = true,
				DType = (DamageType)4
			},
			[BoonAxis.DmgFire] = new AxisDef
			{
				GiveAdj = "Blazing",
				GiveNoun = "the Flame",
				TakeAdj = "Smoldering",
				TakeNoun = "the Cinder",
				Noun = "fire damage",
				Percent = true,
				DType = (DamageType)32
			},
			[BoonAxis.DmgFrost] = new AxisDef
			{
				GiveAdj = "Biting",
				GiveNoun = "the Rime",
				TakeAdj = "Melting",
				TakeNoun = "the Slush",
				Noun = "frost damage",
				Percent = true,
				DType = (DamageType)64
			},
			[BoonAxis.DmgPoison] = new AxisDef
			{
				GiveAdj = "Virulent",
				GiveNoun = "the Blight",
				TakeAdj = "Diluted",
				TakeNoun = "the Dilution",
				Noun = "poison damage",
				Percent = true,
				DType = (DamageType)256
			},
			[BoonAxis.DmgLightning] = new AxisDef
			{
				GiveAdj = "Galvanic",
				GiveNoun = "the Bolt",
				TakeAdj = "Faded",
				TakeNoun = "the Flicker",
				Noun = "lightning damage",
				Percent = true,
				DType = (DamageType)128
			},
			[BoonAxis.DmgSpirit] = new AxisDef
			{
				GiveAdj = "Consecrated",
				GiveNoun = "the Smite",
				TakeAdj = "Profane",
				TakeNoun = "the Profane",
				Noun = "spirit damage",
				Percent = true,
				DType = (DamageType)512
			},
			[BoonAxis.SkillXp] = new AxisDef
			{
				GiveAdj = "Apt",
				GiveNoun = "the Prodigy",
				TakeAdj = "Dull-witted",
				TakeNoun = "the Dullard",
				Noun = "skill experience",
				Percent = true
			},
			[BoonAxis.AttackSpeed] = new AxisDef
			{
				GiveAdj = "Quick",
				GiveNoun = "the Tempo",
				TakeAdj = "Ponderous",
				TakeNoun = "the Lag",
				Noun = "attack speed",
				Percent = true
			},
			[BoonAxis.StaggerDealt] = new AxisDef
			{
				GiveAdj = "Jarring",
				GiveNoun = "the Jolt",
				TakeAdj = "Gentle",
				TakeNoun = "the Lull",
				Noun = "stagger dealt",
				Percent = true
			},
			[BoonAxis.BackstabDealt] = new AxisDef
			{
				GiveAdj = "Insidious",
				GiveNoun = "the Ambush",
				TakeAdj = "Forthright",
				TakeNoun = "the Fair Fight",
				Noun = "backstab damage",
				Percent = true
			},
			[BoonAxis.CrouchSpeed] = new AxisDef
			{
				GiveAdj = "Prowling",
				GiveNoun = "the Prowl",
				TakeAdj = "Creeping",
				TakeNoun = "the Crawl",
				Noun = "crouch speed",
				Percent = true
			},
			[BoonAxis.JumpHeight] = new AxisDef
			{
				GiveAdj = "Leaping",
				GiveNoun = "the Leap",
				TakeAdj = "Earthbound",
				TakeNoun = "the Weight",
				Noun = "jump height",
				Percent = true
			},
			[BoonAxis.Survival] = new AxisDef
			{
				GiveAdj = "Hardy",
				GiveNoun = "the Hearth",
				TakeAdj = "Frail",
				TakeNoun = "the Hunger",
				Noun = "food & rest duration",
				Percent = true,
				General = true
			},
			[BoonAxis.WoodCutting] = new AxisDef
			{
				GiveAdj = "Timberborn",
				GiveNoun = "the Axe",
				TakeAdj = "Splintered",
				TakeNoun = "the Splinter",
				Noun = "woodcutting",
				Percent = false
			},
			[BoonAxis.Pickaxes] = new AxisDef
			{
				GiveAdj = "Delving",
				GiveNoun = "the Vein",
				TakeAdj = "Blunt-tipped",
				TakeNoun = "the Rubble",
				Noun = "mining",
				Percent = false
			},
			[BoonAxis.FoodDuration] = new AxisDef
			{
				GiveAdj = "Sated",
				GiveNoun = "the Feast",
				TakeAdj = "Starved",
				TakeNoun = "the Famine",
				Noun = "food duration",
				Percent = true
			},
			[BoonAxis.RestedDuration] = new AxisDef
			{
				GiveAdj = "Restful",
				GiveNoun = "Repose",
				TakeAdj = "Restless",
				TakeNoun = "the Vigil",
				Noun = "rested duration",
				Percent = true
			},
			[BoonAxis.BlockForce] = new AxisDef
			{
				GiveAdj = "Immovable",
				GiveNoun = "the Rampart",
				TakeAdj = "Yielding",
				TakeNoun = "the Give",
				Noun = "block force",
				Percent = true
			}
		};

		internal static readonly BoonAxis[] DamageAxes = new BoonAxis[8]
		{
			BoonAxis.DmgBlunt,
			BoonAxis.DmgSlash,
			BoonAxis.DmgPierce,
			BoonAxis.DmgFire,
			BoonAxis.DmgFrost,
			BoonAxis.DmgPoison,
			BoonAxis.DmgLightning,
			BoonAxis.DmgSpirit
		};

		internal static readonly BoonAxis[] All = (BoonAxis[])Enum.GetValues(typeof(BoonAxis));

		internal static readonly HashSet<BoonAxis> DefenseParts = new HashSet<BoonAxis>
		{
			BoonAxis.ArmorPct,
			BoonAxis.Parry,
			BoonAxis.Stagger,
			BoonAxis.FallDamage,
			BoonAxis.BlockForce
		};

		internal static readonly HashSet<BoonAxis> StaminaLeaves = new HashSet<BoonAxis>
		{
			BoonAxis.AtkStamina,
			BoonAxis.RunStamina,
			BoonAxis.JumpStamina,
			BoonAxis.BlockStamina,
			BoonAxis.DodgeStamina,
			BoonAxis.SwimStamina,
			BoonAxis.SneakStamina,
			BoonAxis.BuildStamina
		};

		private static readonly HashSet<BoonAxis> DamageLeafSet = new HashSet<BoonAxis>(DamageAxes);

		internal static readonly BoonAxis[] NumericAxes = All.Where((BoonAxis a) => !Def[a].Categorical).ToArray();

		internal static readonly BoonAxis[] ResistAxes = new BoonAxis[8]
		{
			BoonAxis.ResBlunt,
			BoonAxis.ResSlash,
			BoonAxis.ResPierce,
			BoonAxis.ResFire,
			BoonAxis.ResFrost,
			BoonAxis.ResPoison,
			BoonAxis.ResLightning,
			BoonAxis.ResSpirit
		};

		internal static float Weight(BoonAxis a)
		{
			AxisDef axisDef = Def[a];
			if (axisDef.General)
			{
				return BoonCfg.WeightGeneral;
			}
			if (axisDef.Categorical)
			{
				return BoonCfg.WeightResist;
			}
			if (DamageLeafSet.Contains(a))
			{
				return BoonCfg.WeightDmgType;
			}
			if (StaminaLeaves.Contains(a))
			{
				return BoonCfg.WeightStamLeaf;
			}
			return BoonCfg.WeightBase;
		}

		internal static bool IsBaseline(BoonAxis a)
		{
			AxisDef axisDef = Def[a];
			if (!axisDef.General && !axisDef.Categorical && !DamageLeafSet.Contains(a))
			{
				return !StaminaLeaves.Contains(a);
			}
			return false;
		}

		internal static DamageModifier Category(int net)
		{
			if (net < 7)
			{
				if (net < 4)
				{
					if (net < 1)
					{
						if (net > -7)
						{
							if (net > -4)
							{
								if (net <= -1)
								{
									return (DamageModifier)8;
								}
								return (DamageModifier)0;
							}
							return (DamageModifier)2;
						}
						return (DamageModifier)6;
					}
					return (DamageModifier)7;
				}
				return (DamageModifier)1;
			}
			return (DamageModifier)5;
		}

		internal static string CatText(int net)
		{
			if (net < 7)
			{
				if (net < 4)
				{
					if (net < 1)
					{
						if (net > -7)
						{
							if (net > -4)
							{
								if (net > -1)
								{
									return "";
								}
								return "Slightly weak";
							}
							return "Weak";
						}
						return "Very weak";
					}
					return "Slightly resistant";
				}
				return "Resistant";
			}
			return "Very resistant";
		}
	}
	internal struct AxisRoll
	{
		public BoonAxis Axis;

		public int Net;
	}
	internal sealed class Boon
	{
		public int Rarity;

		public KeystoneId Keystone;

		public readonly List<AxisRoll> Rolls = new List<AxisRoll>();

		public bool IsKeystone => Keystone != KeystoneId.None;

		public string Desc
		{
			get
			{
				if (!IsKeystone)
				{
					return "";
				}
				return Keystones.Def[Keystone].Desc;
			}
		}

		public string Name
		{
			get
			{
				if (IsKeystone)
				{
					return Keystones.Def[Keystone].Name;
				}
				AxisRoll axisRoll = default(AxisRoll);
				AxisRoll axisRoll2 = default(AxisRoll);
				bool flag = false;
				bool flag2 = false;
				foreach (AxisRoll roll in Rolls)
				{
					if (roll.Net > 0 && (!flag || roll.Net > axisRoll.Net))
					{
						axisRoll = roll;
						flag = true;
					}
					if (roll.Net < 0 && (!flag2 || roll.Net < axisRoll2.Net))
					{
						axisRoll2 = roll;
						flag2 = true;
					}
				}
				string obj = (flag ? Axes.Def[axisRoll.Axis].GiveAdj : "Hollow");
				string text = (flag2 ? Axes.Def[axisRoll2.Axis].TakeNoun : (flag ? Axes.Def[axisRoll.Axis].GiveNoun : "Nothing"));
				return obj + " Boon of " + text;
			}
		}

		public static string Line(AxisRoll r)
		{
			AxisDef axisDef = Axes.Def[r.Axis];
			if (axisDef.Categorical)
			{
				return Axes.CatText(r.Net) + " to " + axisDef.Noun;
			}
			bool num = r.Net > 0;
			int num2 = Math.Abs(r.Net);
			string text = ((num ^ axisDef.Cost) ? "+" : "-");
			string text2 = (axisDef.Percent ? "%" : "");
			return $"{text}{num2}{text2} {axisDef.Noun}";
		}

		public string Serialize()
		{
			return $"{(int)Keystone},{Rarity}," + string.Join(";", Rolls.Select((AxisRoll r) => $"{(int)r.Axis}:{r.Net}"));
		}

		public static Boon Deserialize(string s)
		{
			string[] array = s.Split(',');
			Boon boon = new Boon
			{
				Keystone = (KeystoneId)int.Parse(array[0]),
				Rarity = int.Parse(array[1])
			};
			if (array.Length > 2 && array[2].Length > 0)
			{
				string[] array2 = array[2].Split(';');
				foreach (string text in array2)
				{
					if (text.Length != 0)
					{
						string[] array3 = text.Split(':');
						boon.Rolls.Add(new AxisRoll
						{
							Axis = (BoonAxis)int.Parse(array3[0]),
							Net = int.Parse(array3[1])
						});
					}
				}
			}
			return boon;
		}
	}
	internal static class BoonRoller
	{
		private static readonly Random Rng = new Random();

		private static int Roll010()
		{
			return (int)Math.Round(Rng.NextDouble() * 10.0);
		}

		private static int RollCount()
		{
			float attrW = BoonCfg.AttrW1;
			float attrW2 = BoonCfg.AttrW2;
			float attrW3 = BoonCfg.AttrW3;
			float attrW4 = BoonCfg.AttrW4;
			float num = attrW + attrW2 + attrW3 + attrW4;
			if (num <= 0f)
			{
				return 1;
			}
			double num2 = Rng.NextDouble() * (double)num;
			if (num2 < (double)attrW)
			{
				return 1;
			}
			num2 -= (double)attrW;
			if (num2 < (double)attrW2)
			{
				return 2;
			}
			num2 -= (double)attrW2;
			if (num2 < (double)attrW3)
			{
				return 3;
			}
			return 4;
		}

		private static bool PyrrhicActive()
		{
			if (BoonCfg.LegendaryEnabled(KeystoneId.Pyrrhic) && BoonHud.State != null)
			{
				return BoonHud.State.HasKeystone(KeystoneId.Pyrrhic);
			}
			return false;
		}

		private static float WeightOf(BoonAxis a, bool pyr)
		{
			float num = Axes.Weight(a);
			if (pyr && Axes.IsBaseline(a))
			{
				num *= BoonCfg.PyrrhicBaseFactor;
			}
			return num;
		}

		private static BoonAxis PickAxis()
		{
			bool pyr = PyrrhicActive();
			float num = 0f;
			BoonAxis[] all = Axes.All;
			foreach (BoonAxis a in all)
			{
				num += WeightOf(a, pyr);
			}
			if (num <= 0f)
			{
				return Axes.All[Rng.Next(Axes.All.Length)];
			}
			double num2 = Rng.NextDouble() * (double)num;
			all = Axes.All;
			foreach (BoonAxis boonAxis in all)
			{
				num2 -= (double)WeightOf(boonAxis, pyr);
				if (num2 < 0.0)
				{
					return boonAxis;
				}
			}
			return Axes.All[Axes.All.Length - 1];
		}

		private static Boon RollNumeric()
		{
			int num = RollCount();
			Dictionary<BoonAxis, int> dictionary = new Dictionary<BoonAxis, int>();
			for (int i = 0; i < num; i++)
			{
				bool flag = i == 0 || Rng.NextDouble() < 0.5;
				BoonAxis key = PickAxis();
				int num2 = Roll010();
				dictionary.TryGetValue(key, out var value);
				dictionary[key] = value + (flag ? num2 : (-num2));
			}
			Boon boon = new Boon();
			foreach (KeyValuePair<BoonAxis, int> item in dictionary)
			{
				if (item.Value != 0)
				{
					boon.Rolls.Add(new AxisRoll
					{
						Axis = item.Key,
						Net = item.Value
					});
				}
			}
			if (boon.Rolls.Count == 1 && boon.Rolls[0].Net < 1)
			{
				boon.Rolls[0] = new AxisRoll
				{
					Axis = boon.Rolls[0].Axis,
					Net = 1
				};
			}
			if (boon.Rolls.Count == 0)
			{
				boon.Rolls.Add(new AxisRoll
				{
					Axis = PickAxis(),
					Net = 1
				});
			}
			boon.Rarity = RarityOf(boon);
			return boon;
		}

		private static int RarityOf(Boon b)
		{
			int count = b.Rolls.Count;
			int val = ((count > 2) ? ((count == 3) ? 1 : 2) : 0);
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			foreach (AxisRoll roll in b.Rolls)
			{
				if (roll.Net > 0)
				{
					num++;
					num3 += roll.Net;
				}
				else
				{
					num2++;
					num4 += -roll.Net;
				}
			}
			float num5 = (float)(num - num2) + (float)(num3 - num4) / 4f;
			int val2 = ((num5 >= 6f) ? 2 : ((num5 >= 3f) ? 1 : 0));
			int num6 = Math.Max(val, val2);
			if (b.Rolls.Any((AxisRoll r) => Axes.Def[r.Axis].General))
			{
				num6 = Math.Max(num6, 2);
			}
			return num6;
		}

		private static Boon RollKeystone(HashSet<KeystoneId> owned, HashSet<KeystoneId> offered)
		{
			KeystoneId[] array = Keystones.All.Where((KeystoneId k) => Keystones.Available(k) && !owned.Contains(k) && !offered.Contains(k)).ToArray();
			if (array.Length == 0)
			{
				return null;
			}
			return new Boon
			{
				Keystone = array[Rng.Next(array.Length)],
				Rarity = 3
			};
		}

		private static string Signature(Boon b)
		{
			return string.Join(";", from r in b.Rolls
				select (int)r.Axis into x
				orderby x
				select x);
		}

		internal static List<Boon> Draw()
		{
			List<Boon> list = new List<Boon>();
			HashSet<string> hashSet = new HashSet<string>();
			HashSet<KeystoneId> hashSet2 = new HashSet<KeystoneId>();
			HashSet<KeystoneId> owned = ((BoonHud.State != null) ? new HashSet<KeystoneId>(from b in BoonHud.State.Boons
				where b.IsKeystone
				select b.Keystone) : new HashSet<KeystoneId>());
			int num = 0;
			while (list.Count < BoonCfg.DrawCount && num++ < 400)
			{
				Boon boon = null;
				if (Rng.NextDouble() < (double)BoonCfg.LegendaryChance)
				{
					boon = RollKeystone(owned, hashSet2);
				}
				if (boon == null)
				{
					boon = RollNumeric();
				}
				if (boon.IsKeystone)
				{
					if (hashSet2.Add(boon.Keystone))
					{
						list.Add(boon);
					}
				}
				else if (hashSet.Add(Signature(boon)))
				{
					list.Add(boon);
				}
			}
			return list;
		}
	}
	internal sealed class BoonState
	{
		private const string Key = "pilgrim.boons.v1";

		public int Level = 1;

		public int Xp;

		public int Pending;

		public readonly List<Boon> Boons = new List<Boon>();

		public static BoonState Load(Player p)
		{
			BoonState boonState = new BoonState();
			if ((Object)(object)p != (Object)null && p.m_customData != null && p.m_customData.TryGetValue("pilgrim.boons.v1", out var value) && !string.IsNullOrEmpty(value))
			{
				try
				{
					string[] array = value.Split('|');
					boonState.Level = int.Parse(array[0]);
					boonState.Xp = int.Parse(array[1]);
					boonState.Pending = int.Parse(array[2]);
					for (int i = 3; i < array.Length; i++)
					{
						if (array[i].Length > 0)
						{
							boonState.Boons.Add(Boon.Deserialize(array[i]));
						}
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogWarning((object)("[Pilgrim] boon load failed: " + ex.Message));
					}
				}
			}
			return boonState;
		}

		public void Save(Player p)
		{
			if (!((Object)(object)p == (Object)null) && p.m_customData != null)
			{
				List<string> list = new List<string>
				{
					Level.ToString(),
					Xp.ToString(),
					Pending.ToString()
				};
				list.AddRange(Boons.Select((Boon b) => b.Serialize()));
				p.m_customData["pilgrim.boons.v1"] = string.Join("|", list);
			}
		}

		public void AddXp(int amount)
		{
			Xp += amount;
			while (Xp >= BoonCfg.NeedForNext(Level))
			{
				Xp -= BoonCfg.NeedForNext(Level);
				Level++;
				Pending++;
			}
		}

		public void Respec()
		{
			Boons.Clear();
			Pending = 0;
			Level = 1;
			Xp = 0;
		}

		public bool HasKeystone(KeystoneId id)
		{
			return Boons.Any((Boon b) => b.Keystone == id);
		}

		public Dictionary<BoonAxis, int> Totals()
		{
			Dictionary<BoonAxis, int> dictionary = Axes.All.ToDictionary((BoonAxis a) => a, (BoonAxis _) => 0);
			foreach (Boon boon in Boons)
			{
				if (boon.IsKeystone)
				{
					continue;
				}
				foreach (AxisRoll roll in boon.Rolls)
				{
					dictionary[roll.Axis] += roll.Net;
				}
			}
			return dictionary;
		}
	}
	internal static class BoonStats
	{
		private const string SeName = "PilgrimBoons";

		private static readonly int SeHash = StringExtensionMethods.GetStableHashCode("PilgrimBoons");

		private static SE_Stats _template;

		internal static float AtkSpeedMul = 1f;

		internal static float JumpMul = 1f;

		internal static float FoodMul = 1f;

		internal static float RestedMul = 1f;

		internal static float BlockForceMul = 1f;

		internal static int WoodLvl = 0;

		internal static int PickLvl = 0;

		private static float _baseCrouch = -1f;

		internal static void CaptureBase(Player p)
		{
			if ((Object)(object)p != (Object)null && _baseCrouch < 0f)
			{
				_baseCrouch = ((Character)p).m_crouchSpeed;
			}
		}

		internal static void OnSpawn(Player p)
		{
			CaptureBase(p);
			Boon_AttackSpeed.ResetFast();
		}

		private static SE_Stats Template()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_template != (Object)null)
			{
				return _template;
			}
			_template = ScriptableObject.CreateInstance<SE_Stats>();
			((Object)_template).name = "PilgrimBoons";
			((StatusEffect)_template).m_name = "PilgrimBoons";
			((StatusEffect)_template).m_ttl = 0f;
			((StatusEffect)_template).m_icon = null;
			_template.m_modifyAttackSkill = (SkillType)999;
			return _template;
		}

		internal static void Apply(Player p, BoonState st)
		{
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Invalid comparison between Unknown and I4
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Invalid comparison between Unknown and I4
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Expected I4, but got Unknown
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Invalid comparison between Unknown and I4
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Invalid comparison between Unknown and I4
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_047c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Invalid comparison between Unknown and I4
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Invalid comparison between Unknown and I4
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)p == (Object)null)
			{
				return;
			}
			KeystoneNet.WriteOwned(p, st);
			SEMan sEMan = ((Character)p).GetSEMan();
			if (sEMan == null)
			{
				return;
			}
			StatusEffect statusEffect = sEMan.GetStatusEffect(SeHash);
			SE_Stats val = (SE_Stats)(object)((statusEffect is SE_Stats) ? statusEffect : null);
			if ((Object)(object)val == (Object)null)
			{
				sEMan.AddStatusEffect((StatusEffect)(object)Template(), false, 0, 0f, (short)(-1));
				StatusEffect statusEffect2 = sEMan.GetStatusEffect(SeHash);
				val = (SE_Stats)(object)((statusEffect2 is SE_Stats) ? statusEffect2 : null);
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Dictionary<BoonAxis, int> dictionary = st.Totals();
			val.m_damageModifier = 1f + (float)dictionary[BoonAxis.Damage] / 100f;
			val.m_speedModifier = (float)dictionary[BoonAxis.MoveSpeed] / 100f;
			val.m_healthRegenMultiplier = 1f + (float)dictionary[BoonAxis.HpRegen] / 100f;
			val.m_staminaRegenMultiplier = 1f + (float)dictionary[BoonAxis.StamRegen] / 100f;
			val.m_addArmor = dictionary[BoonAxis.FlatArmor];
			val.m_modifyAttackSkill = (SkillType)999;
			float num = dictionary[BoonAxis.StaminaUse];
			val.m_attackStaminaUseModifier = 0f - ((float)dictionary[BoonAxis.AtkStamina] + num) / 100f;
			val.m_runStaminaUseModifier = 0f - ((float)dictionary[BoonAxis.RunStamina] + num) / 100f;
			val.m_jumpStaminaUseModifier = 0f - ((float)dictionary[BoonAxis.JumpStamina] + num) / 100f;
			val.m_blockStaminaUseModifier = 0f - ((float)dictionary[BoonAxis.BlockStamina] + num) / 100f;
			val.m_dodgeStaminaUseModifier = 0f - ((float)dictionary[BoonAxis.DodgeStamina] + num) / 100f;
			val.m_swimStaminaUseModifier = 0f - ((float)dictionary[BoonAxis.SwimStamina] + num) / 100f;
			val.m_sneakStaminaUseModifier = 0f - ((float)dictionary[BoonAxis.SneakStamina] + num) / 100f;
			val.m_homeItemStaminaUseModifier = 0f - ((float)dictionary[BoonAxis.BuildStamina] + num) / 100f;
			float num2 = dictionary[BoonAxis.Defense];
			val.m_staggerModifier = 0f - ((float)dictionary[BoonAxis.Stagger] + num2) / 100f;
			val.m_fallDamageModifier = 0f - ((float)dictionary[BoonAxis.FallDamage] + num2) / 100f;
			val.m_armorMultiplier = ((float)dictionary[BoonAxis.ArmorPct] + num2) / 100f;
			val.m_timedBlockBonus = ((float)dictionary[BoonAxis.Parry] + num2) / 100f;
			BlockForceMul = 1f + ((float)dictionary[BoonAxis.BlockForce] + num2) / 100f;
			val.m_eitrRegenMultiplier = 1f + (float)dictionary[BoonAxis.EitrRegen] / 100f;
			val.m_swimSpeedModifier = (float)dictionary[BoonAxis.SwimSpeed] / 100f;
			val.m_stealthModifier = 0f;
			float num3 = dictionary[BoonAxis.CarryWeight];
			if (st.HasKeystone(KeystoneId.Regret))
			{
				num3 += p.m_maxCarryWeight;
			}
			val.m_addMaxCarryWeight = num3;
			float num4 = dictionary[BoonAxis.Stealth];
			if (st.HasKeystone(KeystoneId.Dread))
			{
				num4 += 30f;
			}
			val.m_skillLevel = (SkillType)((num4 != 0f) ? 101 : 0);
			val.m_skillLevelModifier = num4;
			float num5 = dictionary[BoonAxis.SkillXp];
			val.m_raiseSkill = (SkillType)((num5 != 0f) ? 999 : 0);
			val.m_raiseSkillModifier = 1f + num5 / 100f;
			DamageTypes percentigeDamageModifiers = default(DamageTypes);
			BoonAxis[] damageAxes = Axes.DamageAxes;
			foreach (BoonAxis key in damageAxes)
			{
				float num6 = (float)dictionary[key] / 100f;
				if (num6 == 0f)
				{
					continue;
				}
				DamageType dType = Axes.Def[key].DType;
				if ((int)dType <= 64)
				{
					switch (dType - 1)
					{
					case 0:
						percentigeDamageModifiers.m_blunt += num6;
						continue;
					case 1:
						percentigeDamageModifiers.m_slash += num6;
						continue;
					case 3:
						percentigeDamageModifiers.m_pierce += num6;
						continue;
					case 2:
						continue;
					}
					if ((int)dType != 32)
					{
						if ((int)dType == 64)
						{
							percentigeDamageModifiers.m_frost += num6;
						}
					}
					else
					{
						percentigeDamageModifiers.m_fire += num6;
					}
				}
				else if ((int)dType != 128)
				{
					if ((int)dType != 256)
					{
						if ((int)dType == 512)
						{
							percentigeDamageModifiers.m_spirit += num6;
						}
					}
					else
					{
						percentigeDamageModifiers.m_poison += num6;
					}
				}
				else
				{
					percentigeDamageModifiers.m_lightning += num6;
				}
			}
			if (st.HasKeystone(KeystoneId.Wrath))
			{
				percentigeDamageModifiers.m_slash += 1f;
			}
			if (st.HasKeystone(KeystoneId.Temerity))
			{
				percentigeDamageModifiers.m_blunt += 1f;
			}
			if (st.HasKeystone(KeystoneId.Contempt))
			{
				percentigeDamageModifiers.m_pierce += 1f;
			}
			val.m_percentigeDamageModifiers = percentigeDamageModifiers;
			List<DamageModPair> list = new List<DamageModPair>();
			damageAxes = Axes.ResistAxes;
			foreach (BoonAxis key2 in damageAxes)
			{
				DamageModifier val2 = Axes.Category(dictionary[key2]);
				if ((int)val2 != 0)
				{
					list.Add(new DamageModPair
					{
						m_type = Axes.Def[key2].DType,
						m_modifier = val2
					});
				}
			}
			val.m_mods = list;
			AtkSpeedMul = 1f + (float)dictionary[BoonAxis.AttackSpeed] / 100f;
			JumpMul = 1f + (float)dictionary[BoonAxis.JumpHeight] / 100f;
			float num7 = dictionary[BoonAxis.Survival];
			FoodMul = 1f + ((float)dictionary[BoonAxis.FoodDuration] + num7) / 100f;
			RestedMul = 1f + ((float)dictionary[BoonAxis.RestedDuration] + num7) / 100f;
			WoodLvl = dictionary[BoonAxis.WoodCutting];
			PickLvl = dictionary[BoonAxis.Pickaxes];
			CaptureBase(p);
			if (_baseCrouch > 0f)
			{
				((Character)p).m_crouchSpeed = _baseCrouch * (1f + (float)dictionary[BoonAxis.CrouchSpeed] / 100f);
			}
			KeystoneNet.WriteOffense(p, dictionary[BoonAxis.StaggerDealt], dictionary[BoonAxis.BackstabDealt]);
		}

		internal static SE_Stats Active(SEMan seman)
		{
			StatusEffect obj = ((seman != null) ? seman.GetStatusEffect(SeHash) : null);
			return (SE_Stats)(object)((obj is SE_Stats) ? obj : null);
		}

		internal static void Remove(Player p)
		{
			SEMan val = ((p != null) ? ((Character)p).GetSEMan() : null);
			if (val