Decompiled source of LevelStatRewards v1.0.0

BepInEx/plugins/LevelStatRewards.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon.Movement;
using Sparroh.UI;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
internal static class BonusStatPatches
{
	[HarmonyPatch(typeof(Upgrade), "ApplyRandomStatUpgrade")]
	private static class ApplyRandomStatUpgrade_Patch
	{
		private static bool Prefix()
		{
			return false;
		}
	}

	[HarmonyPatch(typeof(Upgrade), "GetStatList")]
	private static class GetStatList_Patch
	{
		private static void Postfix(Upgrade __instance, ref string __result)
		{
			if (!((Object)(object)__instance == (Object)null) && __instance.ApplyStatUpgrades && !string.IsNullOrEmpty(__result))
			{
				__result = StripBonusColorBlock(__result);
			}
		}
	}

	private static string StripBonusColorBlock(string properties)
	{
		int num = properties.IndexOf("<color=#FFD58D>", StringComparison.Ordinal);
		if (num < 0)
		{
			num = properties.IndexOf("<color=#ffd58d>", StringComparison.Ordinal);
		}
		if (num < 0)
		{
			return properties;
		}
		int num2 = properties.IndexOf("</color>", num, StringComparison.Ordinal);
		if (num2 < 0)
		{
			return properties;
		}
		num2 += "</color>".Length;
		StringBuilder stringBuilder = new StringBuilder(properties.Length);
		stringBuilder.Append(properties, 0, num);
		stringBuilder.Append(properties, num2, properties.Length - num2);
		string text = stringBuilder.ToString();
		while (text.Contains("\n\n\n"))
		{
			text = text.Replace("\n\n\n", "\n\n");
		}
		return text.Trim();
	}
}
[HarmonyPatch(typeof(GearDetailsWindow))]
internal static class GearDetailsWindowPatches
{
	[HarmonyPostfix]
	[HarmonyPatch("Setup")]
	private static void Setup_Postfix(GearDetailsWindow __instance, IUpgradable upgradable)
	{
		try
		{
			if (upgradable != null)
			{
				GearStatButton.SetCurrentGear(upgradable);
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = LevelStatRewardsPlugin.Log;
			if (log != null)
			{
				log.LogDebug((object)("GearDetails Setup: " + ex.Message));
			}
		}
	}
}
public static class GearStatButton
{
	public const string BarId = "levelstatrewards.stats";

	public const int Order = 155;

	private static IUpgradable _currentGear;

	private static bool _registered;

	public static IUpgradable CurrentGear => _currentGear;

	public static void SetCurrentGear(IUpgradable gear)
	{
		_currentGear = gear;
	}

	public static void Tick()
	{
		if (!GearActionBar.IsGearMenuOpen())
		{
			if (_registered)
			{
				GearActionBar.SetSlotVisible("levelstatrewards.stats", false);
			}
			return;
		}
		try
		{
			Menu instance = Menu.Instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				WindowSystem windowSystem = instance.WindowSystem;
				obj = ((windowSystem != null) ? windowSystem.GetTop() : null);
			}
			GearDetailsWindow val = (GearDetailsWindow)((obj is GearDetailsWindow) ? obj : null);
			if (val != null)
			{
				IUpgradable upgradablePrefab = val.UpgradablePrefab;
				if (upgradablePrefab != null)
				{
					_currentGear = upgradablePrefab;
				}
			}
		}
		catch
		{
		}
		if (_currentGear == null)
		{
			if (_registered)
			{
				GearActionBar.SetSlotVisible("levelstatrewards.stats", false);
			}
		}
		else
		{
			EnsureRegistered();
			GearActionBar.SetSlotVisible("levelstatrewards.stats", true);
			GearActionBar.SetText("levelstatrewards.stats", BuildLabel(_currentGear));
			GearActionBar.SetStyle("levelstatrewards.stats", (UIButtonStyle)(StatAllocationStore.GetUnspent(_currentGear) > 0));
		}
	}

	public static void Unregister()
	{
		try
		{
			GearActionBar.Unregister("levelstatrewards.stats");
		}
		catch
		{
		}
		_registered = false;
		_currentGear = null;
	}

	private static void EnsureRegistered()
	{
		GearActionBar.Register("levelstatrewards.stats", BuildLabel(_currentGear), 155, (Action)OnClicked, (UIButtonStyle)0);
		_registered = true;
	}

	private static string BuildLabel(IUpgradable gear)
	{
		if (gear == null)
		{
			return "Level Stats";
		}
		int unspent = StatAllocationStore.GetUnspent(gear);
		if (unspent <= 0)
		{
			return "Level Stats";
		}
		return $"Level Stats ({unspent})";
	}

	private static void OnClicked()
	{
		try
		{
			if (_currentGear != null)
			{
				StatAllocationWindow.Open(_currentGear);
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log = LevelStatRewardsPlugin.Log;
			if (log != null)
			{
				log.LogError((object)$"Open allocation UI failed: {arg}");
			}
		}
	}
}
public static class ModBalance
{
	public const int LevelsPerPoint = 3;

	public const int LevelCapForPoints = 30;

	public const int MaxPointsPerGear = 10;

	public const float PercentPerPoint = 10f;

	public const float PercentPerPointMinBetter = -10f;
}
[BepInPlugin("sparroh.levelstatrewards", "LevelStatRewards", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[MycoMod(/*Could not decode attribute arguments.*/)]
public class LevelStatRewardsPlugin : BaseUnityPlugin
{
	public const string PluginGUID = "sparroh.levelstatrewards";

	public const string PluginName = "LevelStatRewards";

	public const string PluginVersion = "1.0.0";

	internal static ManualLogSource Log;

	private Harmony _harmony;

	private void Awake()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		try
		{
			StatAllocationStore.Load();
		}
		catch (Exception arg)
		{
			Log.LogError((object)$"Init failed: {arg}");
			return;
		}
		_harmony = new Harmony("sparroh.levelstatrewards");
		try
		{
			_harmony.PatchAll(typeof(LevelStatRewardsPlugin).Assembly);
			Log.LogInfo((object)"LevelStatRewards v1.0.0 loaded.");
		}
		catch (Exception arg2)
		{
			Log.LogError((object)$"Harmony patch failed: {arg2}");
		}
	}

	private void Update()
	{
		try
		{
			GearStatButton.Tick();
			StatAllocationWindow.Tick();
		}
		catch (Exception arg)
		{
			Log.LogError((object)$"Update error: {arg}");
		}
	}

	private void OnDestroy()
	{
		try
		{
			StatAllocationWindow.DestroyUi();
			GearStatButton.Unregister();
			StatAllocationStore.Save();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)$"OnDestroy error: {arg}");
			}
		}
	}
}
public static class StatAllocationStore
{
	private sealed class EmptyMap : Dictionary<string, int>
	{
		public static readonly EmptyMap Instance = new EmptyMap();
	}

	private static readonly Dictionary<string, Dictionary<string, int>> Allocations = new Dictionary<string, Dictionary<string, int>>(StringComparer.Ordinal);

	private static string FilePath => Path.Combine(Paths.ConfigPath, "sparroh.levelstatrewards.allocations.json");

	public static void Load()
	{
		Allocations.Clear();
		try
		{
			if (File.Exists(FilePath))
			{
				Parse(File.ReadAllText(FilePath));
				ManualLogSource log = LevelStatRewardsPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"Loaded allocations for {Allocations.Count} gear entries.");
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log2 = LevelStatRewardsPlugin.Log;
			if (log2 != null)
			{
				log2.LogError((object)("Failed to load allocations: " + ex.Message));
			}
		}
	}

	public static void Save()
	{
		try
		{
			string directoryName = Path.GetDirectoryName(FilePath);
			if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			File.WriteAllText(FilePath, Serialize());
		}
		catch (Exception ex)
		{
			ManualLogSource log = LevelStatRewardsPlugin.Log;
			if (log != null)
			{
				log.LogError((object)("Failed to save allocations: " + ex.Message));
			}
		}
	}

	public static string GetGearKey(IUpgradable gear)
	{
		if ((Object)(object)((gear != null) ? gear.Info : null) == (Object)null)
		{
			return null;
		}
		return gear.Info.ID.ToString();
	}

	public static int GetPoints(string gearKey, string statId)
	{
		if (string.IsNullOrEmpty(gearKey) || string.IsNullOrEmpty(statId))
		{
			return 0;
		}
		if (!Allocations.TryGetValue(gearKey, out var value))
		{
			return 0;
		}
		if (!value.TryGetValue(statId, out var value2))
		{
			return 0;
		}
		return Mathf.Max(0, value2);
	}

	public static int GetSpent(string gearKey)
	{
		if (string.IsNullOrEmpty(gearKey) || !Allocations.TryGetValue(gearKey, out var value))
		{
			return 0;
		}
		int num = 0;
		foreach (KeyValuePair<string, int> item in value)
		{
			num += Mathf.Max(0, item.Value);
		}
		return num;
	}

	public static int GetGearLevel(IUpgradable gear)
	{
		try
		{
			GearData gearData = PlayerData.GetGearData(gear);
			return (gearData == null) ? 1 : gearData.Level;
		}
		catch
		{
			return 1;
		}
	}

	public static int GetTotalPoints(IUpgradable gear)
	{
		int num = Mathf.Min(GetGearLevel(gear), 30);
		return Mathf.Min(Mathf.Max(0, num / 3), 10);
	}

	public static int GetUnspent(IUpgradable gear)
	{
		string gearKey = GetGearKey(gear);
		return Mathf.Max(0, GetTotalPoints(gear) - GetSpent(gearKey));
	}

	public static bool TryAddPoint(IUpgradable gear, string statId)
	{
		if (gear == null)
		{
			return false;
		}
		string gearKey = GetGearKey(gear);
		if (string.IsNullOrEmpty(gearKey) || StatDefinitions.Find(statId) == null)
		{
			return false;
		}
		if (GetUnspent(gear) <= 0)
		{
			return false;
		}
		if (!Allocations.TryGetValue(gearKey, out var value))
		{
			value = new Dictionary<string, int>(StringComparer.Ordinal);
			Allocations[gearKey] = value;
		}
		value.TryGetValue(statId, out var value2);
		value[statId] = value2 + 1;
		Save();
		return true;
	}

	public static bool TryRemovePoint(IUpgradable gear, string statId)
	{
		if (gear == null)
		{
			return false;
		}
		string gearKey = GetGearKey(gear);
		if (string.IsNullOrEmpty(gearKey) || !Allocations.TryGetValue(gearKey, out var value))
		{
			return false;
		}
		if (!value.TryGetValue(statId, out var value2) || value2 <= 0)
		{
			return false;
		}
		value2--;
		if (value2 <= 0)
		{
			value.Remove(statId);
		}
		else
		{
			value[statId] = value2;
		}
		if (value.Count == 0)
		{
			Allocations.Remove(gearKey);
		}
		Save();
		return true;
	}

	public static void ResetGear(IUpgradable gear)
	{
		string gearKey = GetGearKey(gear);
		if (!string.IsNullOrEmpty(gearKey) && Allocations.Remove(gearKey))
		{
			Save();
		}
	}

	public static void ClampToBudget(IUpgradable gear)
	{
		string gearKey = GetGearKey(gear);
		if (string.IsNullOrEmpty(gearKey) || !Allocations.TryGetValue(gearKey, out var value))
		{
			return;
		}
		int totalPoints = GetTotalPoints(gear);
		int num = 0;
		foreach (KeyValuePair<string, int> item in value)
		{
			num += Mathf.Max(0, item.Value);
		}
		if (num <= totalPoints)
		{
			return;
		}
		List<string> list = new List<string>(value.Keys);
		list.Sort(StringComparer.Ordinal);
		int num2 = num - totalPoints;
		int num3 = list.Count - 1;
		while (num3 >= 0 && num2 > 0)
		{
			string key = list[num3];
			int num4 = value[key];
			int num5 = Mathf.Min(num4, num2);
			num4 -= num5;
			num2 -= num5;
			if (num4 <= 0)
			{
				value.Remove(key);
			}
			else
			{
				value[key] = num4;
			}
			num3--;
		}
		if (value.Count == 0)
		{
			Allocations.Remove(gearKey);
		}
		Save();
	}

	public static IReadOnlyDictionary<string, int> GetMap(string gearKey)
	{
		if (string.IsNullOrEmpty(gearKey) || !Allocations.TryGetValue(gearKey, out var value))
		{
			return EmptyMap.Instance;
		}
		return value;
	}

	private static void Parse(string text)
	{
		text = text.Trim();
		if (text.Length < 2 || text[0] != '{')
		{
			return;
		}
		int i = 1;
		while (i < text.Length)
		{
			SkipWs(text, ref i);
			if (i >= text.Length || text[i] == '}')
			{
				break;
			}
			if (text[i] == ',')
			{
				i++;
				continue;
			}
			if (!TryReadString(text, ref i, out var value))
			{
				break;
			}
			SkipWs(text, ref i);
			if (i >= text.Length || text[i] != ':')
			{
				break;
			}
			i++;
			SkipWs(text, ref i);
			if (i >= text.Length || text[i] != '{')
			{
				break;
			}
			i++;
			Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.Ordinal);
			while (i < text.Length)
			{
				SkipWs(text, ref i);
				if (i >= text.Length || text[i] == '}')
				{
					i++;
					break;
				}
				if (text[i] == ',')
				{
					i++;
					continue;
				}
				if (!TryReadString(text, ref i, out var value2))
				{
					break;
				}
				SkipWs(text, ref i);
				if (i >= text.Length || text[i] != ':')
				{
					break;
				}
				i++;
				SkipWs(text, ref i);
				if (!TryReadInt(text, ref i, out var value3))
				{
					break;
				}
				if (value3 > 0)
				{
					dictionary[value2] = value3;
				}
			}
			if (dictionary.Count > 0)
			{
				Allocations[value] = dictionary;
			}
		}
	}

	private static string Serialize()
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.Append("{\n");
		bool flag = true;
		foreach (KeyValuePair<string, Dictionary<string, int>> allocation in Allocations)
		{
			if (allocation.Value == null || allocation.Value.Count == 0)
			{
				continue;
			}
			if (!flag)
			{
				stringBuilder.Append(",\n");
			}
			flag = false;
			stringBuilder.Append("  \"").Append(Escape(allocation.Key)).Append("\": {\n");
			bool flag2 = true;
			foreach (KeyValuePair<string, int> item in allocation.Value)
			{
				if (item.Value > 0)
				{
					if (!flag2)
					{
						stringBuilder.Append(",\n");
					}
					flag2 = false;
					stringBuilder.Append("    \"").Append(Escape(item.Key)).Append("\": ")
						.Append(item.Value);
				}
			}
			stringBuilder.Append("\n  }");
		}
		stringBuilder.Append("\n}\n");
		return stringBuilder.ToString();
	}

	private static string Escape(string s)
	{
		return s.Replace("\\", "\\\\").Replace("\"", "\\\"");
	}

	private static void SkipWs(string t, ref int i)
	{
		while (i < t.Length && char.IsWhiteSpace(t[i]))
		{
			i++;
		}
	}

	private static bool TryReadString(string t, ref int i, out string value)
	{
		value = null;
		SkipWs(t, ref i);
		if (i >= t.Length || t[i] != '"')
		{
			return false;
		}
		i++;
		StringBuilder stringBuilder = new StringBuilder();
		while (i < t.Length)
		{
			char c = t[i++];
			if (c == '\\' && i < t.Length)
			{
				stringBuilder.Append(t[i++]);
				continue;
			}
			if (c == '"')
			{
				value = stringBuilder.ToString();
				return true;
			}
			stringBuilder.Append(c);
		}
		return false;
	}

	private static bool TryReadInt(string t, ref int i, out int value)
	{
		value = 0;
		SkipWs(t, ref i);
		int num = i;
		if (i < t.Length && t[i] == '-')
		{
			i++;
		}
		while (i < t.Length && char.IsDigit(t[i]))
		{
			i++;
		}
		if (i == num || (i == num + 1 && t[num] == '-'))
		{
			return false;
		}
		return int.TryParse(t.Substring(num, i - num), out value);
	}
}
public static class StatAllocationWindow
{
	private sealed class Row
	{
		public StatDef Def;

		public RectTransform RowRt;

		public UIText Label;

		public UIText Value;

		public UIButton Minus;

		public UIButton Plus;
	}

	private static UIWindow _window;

	private static UIText _header;

	private static IUpgradable _gear;

	private static readonly List<Row> Rows = new List<Row>();

	private static bool _pendingLayout;

	public static void Open(IUpgradable gear)
	{
		if (gear != null)
		{
			_gear = gear;
			StatAllocationStore.ClampToBudget(gear);
			EnsureWindow();
			UIWindow window = _window;
			GearInfo info = gear.Info;
			window.WithTitle((((info != null) ? info.Name : null) ?? "Gear") + " — Level Stats");
			_window.Show();
			Rebuild();
			ForceFullLayout();
			_pendingLayout = true;
		}
	}

	public static void Tick()
	{
		if (_window == null || !_window.IsVisible)
		{
			return;
		}
		if (!GearActionBar.IsGearMenuOpen())
		{
			_window.Hide(true);
			return;
		}
		if (_pendingLayout)
		{
			_pendingLayout = false;
			ForceFullLayout();
			RefreshAllRows();
		}
		RefreshHeader();
	}

	public static void DestroyUi()
	{
		try
		{
			UIWindow window = _window;
			if (window != null)
			{
				window.Destroy();
			}
		}
		catch
		{
		}
		_window = null;
		_header = null;
		Rows.Clear();
		_gear = null;
		_pendingLayout = false;
	}

	private static void EnsureWindow()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		if (_window == null)
		{
			_window = UIWindow.Create("LevelStatRewards", (Vector2?)new Vector2(560f, 640f), "Level Stats", true, true, (int?)5200);
			_window.OnClose((Action)delegate
			{
			});
		}
	}

	private static void Rebuild()
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Expected O, but got Unknown
		Transform content = _window.Content;
		UIHelpers.DestroyChildren(content);
		Rows.Clear();
		EnsureContentLayout(content);
		_header = UIText.Create(content, "Header", "", UITheme.ScaledFontBody, (Color?)UIColors.TextSecondary, (TextAlignmentOptions)514, true);
		GameObject gameObject = _header.GameObject;
		float? num = UITheme.S(72f);
		float? num2 = UITheme.S(56f);
		UIHelpers.EnsureLayoutElement(gameObject, (float?)null, num, num2);
		UIWindow.CreateSectionHeader(content, "Stats");
		foreach (StatDef item in StatDefinitions.ForGear(_gear))
		{
			Rows.Add(CreateRow(content, item));
		}
		RectTransform obj = UIFactory.CreateRect("Footer", content);
		GameObject gameObject2 = ((Component)obj).gameObject;
		num2 = UITheme.S(44f);
		num = UITheme.S(40f);
		UIHelpers.EnsureLayoutElement(gameObject2, (float?)null, num2, num);
		UIFactory.AddHorizontalLayout(((Component)obj).gameObject, UITheme.S(8f), new RectOffset(0, 0, 4, 4), (TextAnchor)4, false, false, true, false);
		UIButton.Create((Transform)(object)obj, "Reset All", (Action)OnReset, (UIButtonStyle)2, (string)null, (float?)UITheme.S(32f)).SetWidth(UITheme.S(120f));
		UIButton.Create((Transform)(object)obj, "Close", (Action)delegate
		{
			_window.Hide(true);
		}, (UIButtonStyle)0, (string)null, (float?)UITheme.S(32f)).SetWidth(UITheme.S(100f));
		RefreshAllRows();
	}

	private static void EnsureContentLayout(Transform content)
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		if (!((Object)(object)content == (Object)null))
		{
			VerticalLayoutGroup val = ((Component)content).GetComponent<VerticalLayoutGroup>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)content).gameObject.AddComponent<VerticalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)val).spacing = UITheme.S(6f);
				((LayoutGroup)val).padding = new RectOffset(4, 4, 4, 4);
			}
			((LayoutGroup)val).childAlignment = (TextAnchor)1;
			((HorizontalOrVerticalLayoutGroup)val).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandWidth = true;
			ContentSizeFitter val2 = ((Component)content).GetComponent<ContentSizeFitter>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = ((Component)content).gameObject.AddComponent<ContentSizeFitter>();
			}
			val2.horizontalFit = (FitMode)0;
			val2.verticalFit = (FitMode)2;
		}
	}

	private static Row CreateRow(Transform parent, StatDef def)
	{
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Expected O, but got Unknown
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		RectTransform val = UIFactory.CreateRect("Row_" + def.Id, parent);
		GameObject gameObject = ((Component)val).gameObject;
		float? num = UITheme.S(40f);
		float? num2 = UITheme.S(36f);
		UIHelpers.EnsureLayoutElement(gameObject, (float?)null, num, num2);
		((HorizontalOrVerticalLayoutGroup)UIFactory.AddHorizontalLayout(((Component)val).gameObject, UITheme.S(6f), new RectOffset(4, 4, 2, 2), (TextAnchor)3, true, false, true, false)).childForceExpandWidth = false;
		Image obj = ((Component)val).gameObject.AddComponent<Image>();
		((Graphic)obj).color = UIColors.WithAlpha(UIColors.PanelBg, 0.35f);
		UIFactory.ApplyWhiteSprite(obj);
		((Graphic)obj).raycastTarget = false;
		UIText val2 = UIText.Create((Transform)(object)val, "Label", def.Label, UITheme.ScaledFontBody, (Color?)UIColors.TextPrimary, (TextAlignmentOptions)513, false);
		LayoutElement obj2 = UIHelpers.EnsureLayoutElement(val2.GameObject, (float?)UITheme.S(180f), (float?)null, (float?)null);
		obj2.flexibleWidth = 1f;
		obj2.minWidth = UITheme.S(100f);
		UIText val3 = UIText.Create((Transform)(object)val, "Value", "0", UITheme.ScaledFontBody, (Color?)UIColors.Sky, (TextAlignmentOptions)514, false);
		LayoutElement obj3 = UIHelpers.EnsureLayoutElement(val3.GameObject, (float?)UITheme.S(130f), (float?)null, (float?)null);
		obj3.minWidth = UITheme.S(100f);
		obj3.flexibleWidth = 0f;
		float num3 = UITheme.S(28f);
		float width = UITheme.S(40f);
		UIButton val4 = UIButton.Create((Transform)(object)val, "-", (Action)null, (UIButtonStyle)0, (string)null, (float?)num3);
		ConfigureFixedButton(val4, width, num3);
		UIButton val5 = UIButton.Create((Transform)(object)val, "+", (Action)null, (UIButtonStyle)1, (string)null, (float?)num3);
		ConfigureFixedButton(val5, width, num3);
		Row row = new Row
		{
			Def = def,
			RowRt = val,
			Label = val2,
			Value = val3,
			Minus = val4,
			Plus = val5
		};
		val4.OnClick((Action)delegate
		{
			OnMinus(row);
		});
		val5.OnClick((Action)delegate
		{
			OnPlus(row);
		});
		return row;
	}

	private static void ConfigureFixedButton(UIButton btn, float width, float height)
	{
		if (btn != null)
		{
			btn.SetWidth(width);
			LayoutElement obj = UIHelpers.EnsureLayoutElement(btn.GameObject, (float?)width, (float?)height, (float?)height);
			obj.minWidth = width;
			obj.flexibleWidth = 0f;
			obj.flexibleHeight = 0f;
			if ((Object)(object)btn.Rect != (Object)null)
			{
				btn.Rect.SetSizeWithCurrentAnchors((Axis)0, width);
				btn.Rect.SetSizeWithCurrentAnchors((Axis)1, height);
			}
			btn.SetInteractable(true);
			btn.ApplyVisualState();
			btn.SetActive(true);
		}
	}

	private static void ForceFullLayout()
	{
		try
		{
			Canvas.ForceUpdateCanvases();
			UIWindow window = _window;
			Transform obj = ((window != null) ? window.Content : null);
			RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			if (val != null)
			{
				LayoutRebuilder.ForceRebuildLayoutImmediate(val);
				foreach (Row row in Rows)
				{
					if ((Object)(object)row?.RowRt != (Object)null)
					{
						LayoutRebuilder.ForceRebuildLayoutImmediate(row.RowRt);
					}
				}
				LayoutRebuilder.ForceRebuildLayoutImmediate(val);
			}
			UIWindow window2 = _window;
			object obj2;
			if (window2 == null)
			{
				obj2 = null;
			}
			else
			{
				UIScrollView scrollView = window2.ScrollView;
				obj2 = ((scrollView != null) ? scrollView.Rect : null);
			}
			if ((Object)obj2 != (Object)null)
			{
				LayoutRebuilder.ForceRebuildLayoutImmediate(_window.ScrollView.Rect);
			}
			Canvas.ForceUpdateCanvases();
		}
		catch (Exception ex)
		{
			ManualLogSource log = LevelStatRewardsPlugin.Log;
			if (log != null)
			{
				log.LogDebug((object)("ForceFullLayout: " + ex.Message));
			}
		}
	}

	private static void OnPlus(Row row)
	{
		if (_gear != null && row?.Def != null && StatAllocationStore.TryAddPoint(_gear, row.Def.Id))
		{
			AfterChange();
		}
	}

	private static void OnMinus(Row row)
	{
		if (_gear != null && row?.Def != null && StatAllocationStore.TryRemovePoint(_gear, row.Def.Id))
		{
			AfterChange();
		}
	}

	private static void OnReset()
	{
		if (_gear != null)
		{
			StatAllocationStore.ResetGear(_gear);
			AfterChange();
		}
	}

	private static void AfterChange()
	{
		RefreshAllRows();
		try
		{
			StatApplier.RefreshAll();
		}
		catch (Exception ex)
		{
			ManualLogSource log = LevelStatRewardsPlugin.Log;
			if (log != null)
			{
				log.LogWarning((object)("Refresh after allocate: " + ex.Message));
			}
		}
	}

	private static void RefreshHeader()
	{
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		if (_header != null && _gear != null)
		{
			int gearLevel = StatAllocationStore.GetGearLevel(_gear);
			int totalPoints = StatAllocationStore.GetTotalPoints(_gear);
			int spent = StatAllocationStore.GetSpent(StatAllocationStore.GetGearKey(_gear));
			int num = Mathf.Max(0, totalPoints - spent);
			_header.Text = $"Level {gearLevel}  ·  {totalPoints}/{10} points " + $"(1 per {3} lv, cap {30})\n" + $"Spent {spent}  ·  Unspent {num}";
			_header.Color = ((num > 0) ? UIColors.Shamrock : UIColors.TextSecondary);
		}
	}

	private static void RefreshAllRows()
	{
		//IL_00c9: 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)
		RefreshHeader();
		if (_gear == null)
		{
			return;
		}
		string gearKey = StatAllocationStore.GetGearKey(_gear);
		int unspent = StatAllocationStore.GetUnspent(_gear);
		foreach (Row row in Rows)
		{
			if (row?.Def != null)
			{
				int points = StatAllocationStore.GetPoints(gearKey, row.Def.Id);
				float num = row.Def.GetPercentPerPoint() * (float)points;
				string arg = ((num >= 0f) ? "+" : "");
				row.Value.Text = ((points == 0) ? "0 pts" : $"{points} pts ({arg}{num:0.#}%)");
				row.Value.Color = ((points > 0) ? UIColors.Sky : UIColors.TextMuted);
				UIButton minus = row.Minus;
				if (minus != null)
				{
					minus.SetActive(true);
				}
				UIButton plus = row.Plus;
				if (plus != null)
				{
					plus.SetActive(true);
				}
				UIButton minus2 = row.Minus;
				if (minus2 != null)
				{
					minus2.SetInteractable(points > 0);
				}
				UIButton plus2 = row.Plus;
				if (plus2 != null)
				{
					plus2.SetInteractable(unspent > 0);
				}
				UIButton minus3 = row.Minus;
				if (minus3 != null)
				{
					minus3.ApplyVisualState();
				}
				UIButton plus3 = row.Plus;
				if (plus3 != null)
				{
					plus3.ApplyVisualState();
				}
			}
		}
	}
}
public static class StatApplier
{
	[HarmonyPatch(typeof(Player), "ApplyUpgrades")]
	private static class PlayerApplyUpgrades_Patch
	{
		private static void Postfix(Player __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).IsOwner)
			{
				ApplyToPlayer(__instance);
			}
		}
	}

	[HarmonyPatch(typeof(Gun), "OnUpgradesEnabled")]
	private static class GunOnUpgradesEnabled_Patch
	{
		private static void Postfix(Gun __instance)
		{
			ApplyToGear((IGear)(object)__instance);
		}
	}

	[HarmonyPatch(typeof(Throwable), "OnUpgradesEnabled")]
	private static class ThrowableOnUpgradesEnabled_Patch
	{
		private static void Postfix(Throwable __instance)
		{
			ApplyToGear((IGear)(object)__instance);
		}
	}

	private static FieldInfo _playerMoveSpeed;

	private static FieldInfo _playerSlideSpeed;

	private static FieldInfo _playerFullSlideDuration;

	private static FieldInfo _playerMaxHealth;

	private static FieldInfo _throwableCooldownData;

	private static bool _fieldsResolved;

	public static void RefreshAll()
	{
		try
		{
			if ((Object)(object)Player.LocalPlayer != (Object)null && ((NetworkBehaviour)Player.LocalPlayer).IsOwner)
			{
				Player.LocalPlayer.ApplyUpgrades(true);
			}
			if (!((Object)(object)Player.LocalPlayer == (Object)null))
			{
				TryRefreshPlayerGear(Player.LocalPlayer);
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = LevelStatRewardsPlugin.Log;
			if (log != null)
			{
				log.LogWarning((object)("RefreshAll failed: " + ex.Message));
			}
		}
	}

	private static void TryRefreshPlayerGear(Player player)
	{
		try
		{
			PropertyInfo propertyInfo = AccessTools.Property(typeof(Player), "Gear");
			object obj = null;
			if (propertyInfo != null)
			{
				obj = propertyInfo.GetValue(player);
			}
			else
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "Gear");
				if (fieldInfo != null)
				{
					obj = fieldInfo.GetValue(player);
				}
			}
			if (obj is IGear[] array)
			{
				IGear[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					SafeApplyGear(array2[i]);
				}
			}
			else
			{
				if (!(obj is IList<IGear> list))
				{
					return;
				}
				{
					foreach (IGear item in list)
					{
						SafeApplyGear(item);
					}
					return;
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = LevelStatRewardsPlugin.Log;
			if (log != null)
			{
				log.LogDebug((object)("TryRefreshPlayerGear: " + ex.Message));
			}
		}
	}

	private static void SafeApplyGear(IGear gear)
	{
		if (gear == null)
		{
			return;
		}
		try
		{
			gear.ApplyUpgrades();
		}
		catch (Exception ex)
		{
			ManualLogSource log = LevelStatRewardsPlugin.Log;
			if (log != null)
			{
				log.LogDebug((object)("ApplyUpgrades gear failed: " + ex.Message));
			}
		}
	}

	public static void ApplyToPlayer(Player player)
	{
		//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_024c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player == (Object)null || !((NetworkBehaviour)player).IsOwner)
		{
			return;
		}
		Character character = player.Character;
		if ((Object)(object)character == (Object)null)
		{
			return;
		}
		StatAllocationStore.ClampToBudget((IUpgradable)(object)character);
		string gearKey = StatAllocationStore.GetGearKey((IUpgradable)(object)character);
		if (string.IsNullOrEmpty(gearKey))
		{
			return;
		}
		EnsurePlayerFields();
		int points = StatAllocationStore.GetPoints(gearKey, "run_speed");
		int points2 = StatAllocationStore.GetPoints(gearKey, "slide_speed");
		int points3 = StatAllocationStore.GetPoints(gearKey, "slide_duration");
		int points4 = StatAllocationStore.GetPoints(gearKey, "max_health");
		int points5 = StatAllocationStore.GetPoints(gearKey, "regen_delay");
		int points6 = StatAllocationStore.GetPoints(gearKey, "healing");
		if (points + points2 + points3 + points4 + points5 + points6 <= 0)
		{
			return;
		}
		try
		{
			if (points > 0 && _playerMoveSpeed != null)
			{
				float num = (float)_playerMoveSpeed.GetValue(player);
				_playerMoveSpeed.SetValue(player, num * StatDefinitions.Find("run_speed").MultiplierForPoints(points));
			}
			if (points2 > 0 && _playerSlideSpeed != null)
			{
				float num2 = (float)_playerSlideSpeed.GetValue(player);
				_playerSlideSpeed.SetValue(player, num2 * StatDefinitions.Find("slide_speed").MultiplierForPoints(points2));
			}
			if (points3 > 0 && _playerFullSlideDuration != null)
			{
				float num3 = (float)_playerFullSlideDuration.GetValue(player);
				_playerFullSlideDuration.SetValue(player, num3 * StatDefinitions.Find("slide_duration").MultiplierForPoints(points3));
			}
			if (points4 > 0)
			{
				float num4 = StatDefinitions.Find("max_health").MultiplierForPoints(points4);
				if (_playerMaxHealth != null)
				{
					float num5 = (float)_playerMaxHealth.GetValue(player) * num4;
					_playerMaxHealth.SetValue(player, num5);
					try
					{
						player.SetMaxHealth(num5);
					}
					catch
					{
					}
				}
			}
			FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "upgradeVariables");
			if (fieldInfo != null)
			{
				UpgradeVariableData val = (UpgradeVariableData)fieldInfo.GetValue(player);
				bool flag = false;
				if (points5 > 0)
				{
					val.noDamageTimeBeforeHealthRegen *= StatDefinitions.Find("regen_delay").MultiplierForPoints(points5);
					flag = true;
				}
				if (points6 > 0)
				{
					val.healingMultiplier *= StatDefinitions.Find("healing").MultiplierForPoints(points6);
					flag = true;
				}
				if (flag)
				{
					fieldInfo.SetValue(player, val);
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = LevelStatRewardsPlugin.Log;
			if (log != null)
			{
				log.LogWarning((object)("ApplyToPlayer failed: " + ex.Message));
			}
		}
	}

	public static void ApplyToGear(IGear gear)
	{
		if (gear == null)
		{
			return;
		}
		object gear2 = ((object)((IUpgradable)gear).Prefab) ?? ((object)gear);
		StatAllocationStore.ClampToBudget((IUpgradable)gear2);
		string gearKey = StatAllocationStore.GetGearKey((IUpgradable)gear2);
		if (string.IsNullOrEmpty(gearKey))
		{
			return;
		}
		try
		{
			Throwable val = (Throwable)(object)((gear is Throwable) ? gear : null);
			if (val != null)
			{
				ApplyThrowable(val, gearKey);
				return;
			}
			IWeapon val2 = (IWeapon)(object)((gear is IWeapon) ? gear : null);
			if (val2 != null)
			{
				ApplyWeapon(val2, gearKey);
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = LevelStatRewardsPlugin.Log;
			if (log != null)
			{
				log.LogWarning((object)("ApplyToGear failed: " + ex.Message));
			}
		}
	}

	private static void ApplyWeapon(IWeapon weapon, string key)
	{
		//IL_0107: 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_0113: 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_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: 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_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		int points = StatAllocationStore.GetPoints(key, "reload");
		int points2 = StatAllocationStore.GetPoints(key, "magazine");
		int points3 = StatAllocationStore.GetPoints(key, "ammo_capacity");
		int points4 = StatAllocationStore.GetPoints(key, "recoil");
		int points5 = StatAllocationStore.GetPoints(key, "spread");
		if (points + points2 + points3 + points4 + points5 > 0)
		{
			ref GunData gunData = ref weapon.GunData;
			if (points > 0)
			{
				gunData.reloadDuration *= StatDefinitions.Find("reload").MultiplierForPoints(points);
			}
			if (points2 > 0)
			{
				float num = StatDefinitions.Find("magazine").MultiplierForPoints(points2);
				gunData.magazineSize = Mathf.Max(1, Mathf.RoundToInt((float)gunData.magazineSize * num));
			}
			if (points3 > 0 && gunData.hasLimitedAmmo)
			{
				float num2 = StatDefinitions.Find("ammo_capacity").MultiplierForPoints(points3);
				gunData.ammoCapacity = Mathf.Max(0, Mathf.RoundToInt((float)gunData.ammoCapacity * num2));
			}
			if (points4 > 0)
			{
				float num3 = StatDefinitions.Find("recoil").MultiplierForPoints(points4);
				ref Vector2 recoilX = ref gunData.recoilData.recoilX;
				recoilX *= num3;
				ref Vector2 recoilY = ref gunData.recoilData.recoilY;
				recoilY *= num3;
				ref Vector2 recoilZ = ref gunData.recoilData.recoilZ;
				recoilZ *= num3;
				ref Vector2 translateZ = ref gunData.recoilData.translateZ;
				translateZ *= num3;
				gunData.recoilData.maxRecoilZ *= num3;
				gunData.recoilData.maxTranslateZ *= num3;
			}
			if (points5 > 0)
			{
				float num4 = StatDefinitions.Find("spread").MultiplierForPoints(points5);
				ref Vector2 spreadSize = ref gunData.spreadData.spreadSize;
				spreadSize *= num4;
				gunData.firstShotSpreadMultiplier *= num4;
			}
		}
	}

	private static void ApplyThrowable(Throwable throwable, string key)
	{
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		int points = StatAllocationStore.GetPoints(key, "grenade_damage");
		int points2 = StatAllocationStore.GetPoints(key, "grenade_cooldown");
		int points3 = StatAllocationStore.GetPoints(key, "explosion_radius");
		if (points + points2 + points3 <= 0)
		{
			return;
		}
		if (throwable != null)
		{
			ref GunData gunData = ref ((IWeapon)throwable).GunData;
			if (points > 0)
			{
				gunData.damage *= StatDefinitions.Find("grenade_damage").MultiplierForPoints(points);
			}
			if (points3 > 0)
			{
				gunData.hitForce *= StatDefinitions.Find("explosion_radius").MultiplierForPoints(points3);
			}
		}
		if (points2 <= 0)
		{
			return;
		}
		EnsureCooldownField();
		if (!(_throwableCooldownData != null))
		{
			return;
		}
		try
		{
			CooldownData val = (CooldownData)_throwableCooldownData.GetValue(throwable);
			float num = StatDefinitions.Find("grenade_cooldown").MultiplierForPoints(points2);
			val.rechargeDuration *= num;
			_throwableCooldownData.SetValue(throwable, val);
		}
		catch (Exception ex)
		{
			ManualLogSource log = LevelStatRewardsPlugin.Log;
			if (log != null)
			{
				log.LogDebug((object)("Cooldown apply: " + ex.Message));
			}
		}
	}

	private static void EnsurePlayerFields()
	{
		if (!_fieldsResolved)
		{
			_fieldsResolved = true;
			_playerMoveSpeed = AccessTools.Field(typeof(Player), "moveSpeed");
			_playerSlideSpeed = AccessTools.Field(typeof(Player), "slideSpeed");
			_playerFullSlideDuration = AccessTools.Field(typeof(Player), "fullSlideDuration");
			_playerMaxHealth = AccessTools.Field(typeof(Player), "maxHealth");
		}
	}

	private static void EnsureCooldownField()
	{
		if (!(_throwableCooldownData != null))
		{
			_throwableCooldownData = AccessTools.Field(typeof(Throwable), "cooldownData");
		}
	}
}
public enum StatCategory
{
	Employee,
	Weapon,
	Grenade
}
public sealed class StatDef
{
	public string Id { get; }

	public string Label { get; }

	public StatCategory Category { get; }

	public float PercentPerPoint { get; }

	public bool InvertDisplay { get; }

	public StatDef(string id, string label, StatCategory category, float percentPerPoint, bool invertDisplay = false)
	{
		Id = id;
		Label = label;
		Category = category;
		PercentPerPoint = percentPerPoint;
		InvertDisplay = invertDisplay;
	}

	public float GetPercentPerPoint()
	{
		return PercentPerPoint;
	}

	public float MultiplierForPoints(int points)
	{
		if (points <= 0)
		{
			return 1f;
		}
		return 1f + PercentPerPoint / 100f * (float)points;
	}
}
public static class StatDefinitions
{
	public const string RunSpeed = "run_speed";

	public const string SlideSpeed = "slide_speed";

	public const string SlideDuration = "slide_duration";

	public const string MaxHealth = "max_health";

	public const string RegenDelay = "regen_delay";

	public const string Healing = "healing";

	public const string Reload = "reload";

	public const string Magazine = "magazine";

	public const string AmmoCapacity = "ammo_capacity";

	public const string Recoil = "recoil";

	public const string Spread = "spread";

	public const string GrenadeDamage = "grenade_damage";

	public const string GrenadeCooldown = "grenade_cooldown";

	public const string ExplosionRadius = "explosion_radius";

	private const float P = 10f;

	private const float N = -10f;

	public static readonly StatDef[] Employee = new StatDef[6]
	{
		new StatDef("run_speed", "Run Speed", StatCategory.Employee, 10f),
		new StatDef("slide_speed", "Slide Speed", StatCategory.Employee, 10f),
		new StatDef("slide_duration", "Slide Duration", StatCategory.Employee, 10f),
		new StatDef("max_health", "Max Health", StatCategory.Employee, 10f),
		new StatDef("regen_delay", "Health Regen Delay", StatCategory.Employee, -10f, invertDisplay: true),
		new StatDef("healing", "Healing Received", StatCategory.Employee, 10f)
	};

	public static readonly StatDef[] Weapon = new StatDef[5]
	{
		new StatDef("reload", "Reload Speed", StatCategory.Weapon, -10f, invertDisplay: true),
		new StatDef("magazine", "Magazine Size", StatCategory.Weapon, 10f),
		new StatDef("ammo_capacity", "Ammo Capacity", StatCategory.Weapon, 10f),
		new StatDef("recoil", "Recoil", StatCategory.Weapon, -10f, invertDisplay: true),
		new StatDef("spread", "Spread", StatCategory.Weapon, -10f, invertDisplay: true)
	};

	public static readonly StatDef[] Grenade = new StatDef[3]
	{
		new StatDef("grenade_damage", "Damage", StatCategory.Grenade, 10f),
		new StatDef("grenade_cooldown", "Cooldown", StatCategory.Grenade, -10f, invertDisplay: true),
		new StatDef("explosion_radius", "Explosion Radius", StatCategory.Grenade, 10f)
	};

	public static IReadOnlyList<StatDef> ForGear(IUpgradable gear)
	{
		//IL_0045: 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_004d: Invalid comparison between Unknown and I4
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Invalid comparison between Unknown and I4
		if (gear == null)
		{
			return Array.Empty<StatDef>();
		}
		if (gear is Character)
		{
			return Employee;
		}
		if (gear is Throwable || gear is GrenadeGear)
		{
			return Grenade;
		}
		if (gear is IWeapon || gear is Gun)
		{
			return Weapon;
		}
		try
		{
			GearType gearType = gear.GearType;
			if ((int)gearType != 3)
			{
				if ((int)gearType == 5)
				{
					return Employee;
				}
				return Weapon;
			}
			return Grenade;
		}
		catch
		{
			return Weapon;
		}
	}

	public static StatDef Find(string id)
	{
		StatDef[] employee = Employee;
		foreach (StatDef statDef in employee)
		{
			if (statDef.Id == id)
			{
				return statDef;
			}
		}
		employee = Weapon;
		foreach (StatDef statDef2 in employee)
		{
			if (statDef2.Id == id)
			{
				return statDef2;
			}
		}
		employee = Grenade;
		foreach (StatDef statDef3 in employee)
		{
			if (statDef3.Id == id)
			{
				return statDef3;
			}
		}
		return null;
	}
}
namespace LevelStatRewards
{
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LevelStatRewards";

		public const string PLUGIN_NAME = "LevelStatRewards";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}