Decompiled source of Lins Better RNG v2.0.5

better.rng.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PracticeCheckBox;
using Rng;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using UnstableLogic;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("better.rng")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("2.0.5.0")]
[assembly: AssemblyInformationalVersion("2.0.5")]
[assembly: AssemblyProduct("better.rng")]
[assembly: AssemblyTitle("better.rng")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.5.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace UnstableLogic
{
	internal static class UnstableRNG
	{
		private static List<Perk> ListOfUnstablePerksOrder = new List<Perk>();

		private static Dictionary<Perk, int> ListOfUnstablePerksSeen = new Dictionary<Perk, int>();

		private static HashSet<string> UnstableItems = new HashSet<string> { "Perk_U_T1_FriendsUpstairs", "Perk_U_T1_HangTight", "Perk_U_T2_BadParent", "Perk_U_T3_Bulletproof", "Perk_U_T2_DiskJockey", "Perk_U_T2_AdoptionDay", "Perk_U_T2_PhysicsGraduate", "Perk_U_TX_TeleporterMalfunction" };

		private static readonly FieldInfo cardsField = AccessTools.Field(typeof(App_PerkPage), "cards");

		public static void EverythingElse(App_PerkPage __instance)
		{
			List<App_PerkPage_Card> list = (List<App_PerkPage_Card>)cardsField.GetValue(__instance);
			List<Perk> perkAssets = CL_AssetManager.GetFullCombinedAssetDatabase().perkAssets;
			if (CheckboxUIHelper.modeIndex > 0)
			{
				Debug.Log((object)"User has chosen non-default behavior");
				CommandConsole.cheatsEnabled = true;
				CommandConsole.hasCheated = true;
			}
			List<Perk> list2 = perkAssets.Where((Perk P) => (int)P.perkType == 3).ToList();
			foreach (Perk item in list2)
			{
				Debug.Log((object)(item.id ?? ""));
			}
			if (ListOfUnstablePerksOrder.Count == 0)
			{
				for (int num = list2.Count - 1; num > 0; num--)
				{
					int num2 = Random.Range(0, num + 1);
					List<Perk> list3 = list2;
					int index = num;
					int index2 = num2;
					Perk value = list2[num2];
					Perk value2 = list2[num];
					list3[index] = value;
					list2[index2] = value2;
				}
				foreach (Perk item2 in list2)
				{
					ListOfUnstablePerksOrder.Add(item2);
					if (!ListOfUnstablePerksSeen.ContainsKey(item2))
					{
						ListOfUnstablePerksSeen[item2] = 0;
					}
				}
			}
			Perk first = null;
			Perk perk = null;
			int num3 = 0;
			int num4 = ListOfUnstablePerksSeen.Values.Max();
			foreach (KeyValuePair<Perk, int> item3 in ListOfUnstablePerksSeen)
			{
				num3 += num4 - item3.Value + 1;
			}
			int num5 = Random.Range(0, num3);
			bool flag = false;
			if (CheckboxUIHelper.modeIndex == 2)
			{
				first = ((IEnumerable<Perk>)ListOfUnstablePerksOrder).FirstOrDefault((Func<Perk, bool>)((Perk p) => !UnstableItems.Contains(p.id)));
			}
			else if (CheckboxUIHelper.modeIndex == 1)
			{
				first = ListOfUnstablePerksOrder[0];
			}
			else
			{
				foreach (KeyValuePair<Perk, int> item4 in ListOfUnstablePerksSeen)
				{
					num5 -= num4 - item4.Value + 1;
					if (num5 < 0)
					{
						first = item4.Key;
						break;
					}
				}
			}
			if ((Object)(object)first == (Object)null)
			{
				flag = true;
			}
			if (flag)
			{
				Debug.Log((object)"Tried to force spawn a non-item unstable but none where in the order.");
				ListOfUnstablePerksOrder.Clear();
				for (int num6 = list2.Count - 1; num6 > 0; num6--)
				{
					int num7 = Random.Range(0, num6 + 1);
					List<Perk> list3 = list2;
					int index2 = num6;
					int index = num7;
					Perk value2 = list2[num7];
					Perk value = list2[num6];
					list3[index2] = value2;
					list2[index] = value;
				}
				foreach (Perk item5 in list2)
				{
					ListOfUnstablePerksOrder.Add(item5);
				}
				first = ListOfUnstablePerksOrder[0];
			}
			ListOfUnstablePerksOrder.Remove(first);
			CardReplacement.ReplaceCards(__instance, 0, first, null);
			if (CheckboxUIHelper.modeIndex == 2)
			{
				perk = ListOfUnstablePerksOrder.First((Perk p) => !UnstableItems.Contains(p.id));
			}
			else if (CheckboxUIHelper.modeIndex == 1)
			{
				perk = ListOfUnstablePerksOrder[0];
			}
			else
			{
				List<KeyValuePair<Perk, int>> list4 = ListOfUnstablePerksSeen.Where((KeyValuePair<Perk, int> kv) => (Object)(object)kv.Key != (Object)(object)first).ToList();
				int num8 = list4.Max((KeyValuePair<Perk, int> kv) => kv.Value);
				int num9 = 0;
				foreach (KeyValuePair<Perk, int> item6 in list4)
				{
					num9 += num8 - item6.Value + 1;
				}
				int num10 = Random.Range(0, num9);
				foreach (KeyValuePair<Perk, int> item7 in list4)
				{
					num10 -= num8 - item7.Value + 1;
					if (num10 < 0)
					{
						perk = item7.Key;
						break;
					}
				}
			}
			CardReplacement.ReplaceCards(__instance, 1, perk, null);
			ListOfUnstablePerksSeen[list[0].perk] = ListOfUnstablePerksSeen.GetValueOrDefault(list[0].perk) + 1;
			ListOfUnstablePerksSeen[list[1].perk] = ListOfUnstablePerksSeen.GetValueOrDefault(list[1].perk) + 1;
		}
	}
}
namespace PracticeCheckBox
{
	internal static class CheckboxUIHelper
	{
		public static bool created;

		public static string foundCanvas;

		public static int starter;

		public static int modeIndex;

		public static void EnsureCreated()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0092: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected O, but got Unknown
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Expected O, but got Unknown
			if (created)
			{
				return;
			}
			Canvas val = Object.FindObjectOfType<Canvas>();
			if (starter == 0)
			{
				foundCanvas = ((Object)val).name;
				starter++;
			}
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)"[PracticeCheckBox] No Canvas found, can't create toggle.");
				return;
			}
			GameObject val2 = new GameObject("PracticeCheckbox_Toggle");
			val2.transform.SetParent(((Component)val).transform, false);
			RectTransform val3 = val2.AddComponent<RectTransform>();
			val3.anchorMin = new Vector2(1f, 0f);
			val3.anchorMax = new Vector2(1f, 0f);
			val3.pivot = new Vector2(1f, 0f);
			val3.anchoredPosition = new Vector2(-50f, 50f);
			val3.sizeDelta = new Vector2(300f, 60f);
			Image val4 = val2.AddComponent<Image>();
			((Graphic)val4).color = new Color(0f, 0f, 0f, 0.4f);
			Button val5 = val2.AddComponent<Button>();
			((Selectable)val5).targetGraphic = (Graphic)(object)val4;
			GameObject val6 = new GameObject("Label");
			val6.transform.SetParent(val2.transform, false);
			RectTransform val7 = val6.AddComponent<RectTransform>();
			val7.anchorMin = new Vector2(0f, 0f);
			val7.anchorMax = new Vector2(1f, 1f);
			val7.offsetMin = new Vector2(20f, 0f);
			val7.offsetMax = new Vector2(0f, 0f);
			Text text = val6.AddComponent<Text>();
			text.text = "[DEFAULT, CHEATS OFF] Frequently seen experimental perks become less likely";
			text.fontSize = 14;
			text.alignment = (TextAnchor)3;
			((Graphic)text).color = Color.white;
			text.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			((UnityEvent)val5.onClick).AddListener((UnityAction)delegate
			{
				modeIndex = (modeIndex + 1) % 3;
				if (modeIndex == 0)
				{
					text.text = "[DEFAULT, CHEATS OFF] Frequently seen experimental perks become less likely";
				}
				if (modeIndex == 1)
				{
					text.text = "[CHEATS ON] You will cycle through experimental perks without repeats";
				}
				if (modeIndex == 2)
				{
					text.text = "[CHEATS ON] You will not encounter item experimental perks, nor repeats";
				}
			});
			created = true;
			Debug.Log((object)("[PracticeCheckBox] Created toggle on canvas " + ((Object)val).name));
		}
	}
}
namespace Rng
{
	[BepInPlugin("better.rng", "better.rng", "2.0.5")]
	public class Plugin : BaseUnityPlugin
	{
		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			new Harmony("com.lin.psuedoRNG").PatchAll();
		}
	}
	public static class CardReplacement
	{
		private static readonly FieldInfo cardsField = AccessTools.Field(typeof(App_PerkPage), "cards");

		private static readonly FieldInfo cardAssetField = AccessTools.Field(typeof(App_PerkPage), "cardAsset");

		private static readonly FieldInfo cardParentField = AccessTools.Field(typeof(App_PerkPage), "cardParent");

		public static void ReplaceCards(App_PerkPage __instance, int index, Perk perk, List<string> seenList)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			App_PerkPage_Card val = (App_PerkPage_Card)cardAssetField.GetValue(__instance);
			Transform val2 = (Transform)cardParentField.GetValue(__instance);
			List<App_PerkPage_Card> list = (List<App_PerkPage_Card>)cardsField.GetValue(__instance);
			App_PerkPage_Card val3 = Object.Instantiate<App_PerkPage_Card>(val, val2.position, Quaternion.identity, val2);
			App_PerkPage_Card component = ((Component)val3).GetComponent<App_PerkPage_Card>();
			Perk val4 = Object.Instantiate<Perk>(perk);
			int num = 0;
			if (CL_GameManager.gMan.GetPlayerBestTravelDistance() > 2000f)
			{
				num = Mathf.RoundToInt((CL_GameManager.gMan.GetPlayerBestTravelDistance() - 2000f) / 200f);
			}
			val4.cost += num;
			val4.cost = Mathf.Min(val4.cost, 99);
			component.Initialize(__instance, val4);
			Object.Destroy((Object)(object)((Component)list[index]).gameObject);
			list[index] = component;
			if (seenList != null)
			{
				seenList.Add(component.perk.id);
				seenList.Add(component.perk.id);
			}
		}
	}
	[HarmonyPatch(typeof(App_PerkPage), "GenerateCards")]
	internal class CardsRNG
	{
		private static List<Perk> allPerks;

		private static Dictionary<string, Perk> perkById;

		private static Dictionary<string, bool> canSpawnById;

		private static int started;

		private static int started2;

		private static int TriesCount;

		private static readonly List<string> ListOfStablePerksSeen = new List<string>();

		private static readonly List<Perk> ListOfCardsBeforeRefreshing = new List<Perk>();

		private static List<Perk> StartingList = new List<Perk>();

		private static int rollCallCounter;

		private static readonly FieldInfo cardsField = AccessTools.Field(typeof(App_PerkPage), "cards");

		private static readonly FieldInfo cardAssetField = AccessTools.Field(typeof(App_PerkPage), "cardAsset");

		private static readonly FieldInfo cardParentField = AccessTools.Field(typeof(App_PerkPage), "cardParent");

		private static readonly FieldInfo cardselectField = AccessTools.Field(typeof(App_PerkPage), "selectedCard");

		public static bool chimneyFlag = false;

		private static HashSet<string> CUnallowed = new HashSet<string>
		{
			"Perk_Debuff_Infected", "Perk_Rho_Blessing_Protection", "Perk_Rho_Blessing_Regeneration", "Perk_Rho_Blessing_Swift", "Perk_Rho_Blessing_Overwhelm", "Perk_U_T1_EmployeeMotivator", "Perk_U_T1_EmployeeRetention", "Perk_U_T1_FriendsUpstairs", "Perk_U_T1_HangTight", "Perk_U_T1_MartialPatch",
			"Perk_U_T1_MetabolicOverdrive", "Perk_U_T1_OnlyClimbing", "Perk_U_T1_RegularPainkillers", "Perk_U_T1_SlowAndSteady", "Perk_U_T2_BadParent", "Perk_U_T2_AdoptionDay", "Perk_U_T3_Bulletproof", "Perk_U_T2_DiskJockey", "Perk_U_T3_PitonEnthusiast", "Perk_U_T2_PulseBladder",
			"Perk_U_T2_ConditionedPolyphagia", "Perk_U_T2_PhysicsGraduate", "Perk_U_T4_FunniestTimeline", "Perk_U_T3_PeripheralBinding", "Perk_U_TX_TeleporterMalfunction"
		};

		private static HashSet<string> Unallowed = new HashSet<string>
		{
			"Perk_Debuff_Infected", "Perk_Rho_Blessing_Protection", "Perk_Rho_Blessing_Regeneration", "Perk_Rho_Blessing_Swift", "Perk_Rho_Blessing_Overwhelm", "Perk_U_T1_EmployeeMotivator", "Perk_U_T1_EmployeeRetention", "Perk_U_T1_FriendsUpstairs", "Perk_U_T1_HangTight", "Perk_U_T1_MartialPatch",
			"Perk_U_T1_MetabolicOverdrive", "Perk_U_T1_OnlyClimbing", "Perk_U_T1_RegularPainkillers", "Perk_U_T1_SlowAndSteady", "Perk_U_T2_BadParent", "Perk_U_T2_AdoptionDay", "Perk_U_T3_Bulletproof", "Perk_U_T2_DiskJockey", "Perk_U_T3_PitonEnthusiast", "Perk_U_T2_PulseBladder",
			"Perk_U_T2_ConditionedPolyphagia", "Perk_U_T2_PhysicsGraduate", "Perk_U_T4_FunniestTimeline", "Perk_U_T3_PeripheralBinding", "Perk_Chimney_CryogenicTouch", "Perk_Chimney_FetalHeating", "Perk_Chimney_FreezingCatabolism", "Perk_Chimney_InsulatedOrgans", "Perk_Chimney_NiceList", "Perk_U_TX_TeleporterMalfunction"
		};

		private static void Postfix(App_PerkPage __instance, bool refresh)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			if ((int)__instance.perkPageType != 1)
			{
				App_PerkPage_Card val = (App_PerkPage_Card)cardAssetField.GetValue(__instance);
				Transform val2 = (Transform)cardParentField.GetValue(__instance);
				List<App_PerkPage_Card> list = (List<App_PerkPage_Card>)cardsField.GetValue(__instance);
				App_PerkPage_Card val3 = (App_PerkPage_Card)cardselectField.GetValue(__instance);
				if (started == 0)
				{
					allPerks = CL_AssetManager.GetFullCombinedAssetDatabase().perkAssets;
					perkById = allPerks.ToDictionary((Perk p) => p.id);
					started++;
				}
				if (started2 <= 0)
				{
					if (started2 == 0)
					{
						foreach (Perk allPerk in allPerks)
						{
							if (allPerk.id == "Perk_PulseOrgan")
							{
								StartingList.Add(allPerk);
								StartingList.Add(allPerk);
							}
						}
					}
					started2++;
					int index = Random.Range(0, StartingList.Count);
					if ((Object)(object)list[2] != (Object)null)
					{
						CardReplacement.ReplaceCards(__instance, 2, StartingList[index], ListOfStablePerksSeen);
					}
					else if ((Object)(object)list[2] == (Object)null && (Object)(object)list[1] != (Object)null)
					{
						CardReplacement.ReplaceCards(__instance, 1, StartingList[index], ListOfStablePerksSeen);
					}
					StartingList.RemoveAt(index);
					for (int i = 0; i < list.Count; i++)
					{
						ListOfStablePerksSeen.Add(list[i].perk.id);
					}
					val3 = list[0];
					for (int j = 0; j < list.Count; j++)
					{
						App_PerkPage_Card val4 = list[j];
						if (j == 0)
						{
							val4.SelectCard();
						}
						else
						{
							val4.DeselectCard();
						}
						val4.UpdateCard();
					}
					return;
				}
				canSpawnById = new Dictionary<string, bool>(allPerks.Count);
				foreach (Perk allPerk2 in allPerks)
				{
					canSpawnById[allPerk2.id] = allPerk2.CanSpawn();
				}
				rollCallCounter++;
				if (ListOfStablePerksSeen.Count == 0)
				{
					for (int k = 0; k < list.Count; k++)
					{
						ListOfStablePerksSeen.Add(list[k].perk.id);
					}
					return;
				}
				Dictionary<string, int> dictionary = new Dictionary<string, int>();
				for (int l = 0; l < ListOfStablePerksSeen.Count; l++)
				{
					if (perkById.TryGetValue(ListOfStablePerksSeen[l], out var value) && value.CanSpawn())
					{
						dictionary.TryGetValue(value.id, out var value2);
						dictionary[value.id] = value2 + 1;
					}
				}
				if (dictionary.Count == 0)
				{
					Debug.Log((object)"[Better RNG] Something went wrong. The Library should NOT be empty rn.");
					Debug.Log((object)$"[Better RNG] Library count: {dictionary.Count} List count: {ListOfStablePerksSeen.Count}");
					return;
				}
				int num = dictionary.Values.Max();
				int num2 = dictionary.Values.Min();
				List<string> list2 = new List<string>();
				List<string> list3 = new List<string>();
				List<string> list4 = new List<string>();
				foreach (KeyValuePair<string, int> item in dictionary)
				{
					if (item.Value == num - 5)
					{
						list2.Add(item.Key);
					}
					if (item.Value == num - 3)
					{
						list3.Add(item.Key);
					}
					if (item.Value == num)
					{
						list4.Add(item.Key);
					}
				}
				List<Perk> list5 = new List<Perk>();
				Debug.Log((object)"Generating restofem ===================");
				Debug.Log((object)"");
				foreach (Perk allPerk3 in allPerks)
				{
					if (allPerk3.CanSpawn())
					{
						int value3;
						bool flag = dictionary.TryGetValue(allPerk3.id, out value3);
						if (!chimneyFlag && !flag && !Unallowed.Contains(allPerk3.id))
						{
							Debug.Log((object)(allPerk3.id + " has not been seen and is allowed"));
							list5.Add(allPerk3);
						}
						else if (chimneyFlag && !flag && !CUnallowed.Contains(allPerk3.id))
						{
							Debug.Log((object)(allPerk3.id + " has not been seen and is allowed"));
							list5.Add(allPerk3);
						}
						else if (flag && value3 < num - 10)
						{
							Debug.Log((object)$"{allPerk3.id} has been seen and has been seen {value3} times");
							list5.Add(allPerk3);
						}
					}
				}
				Debug.Log((object)"");
				Debug.Log((object)"==========================");
				bool flag2 = false;
				Traverse val5 = Traverse.Create((object)__instance);
				if (num <= 2)
				{
					for (int m = 0; m < list.Count; m++)
					{
						ListOfStablePerksSeen.Add(list[m].perk.id);
					}
					return;
				}
				if (TriesCount == 0)
				{
					ListOfCardsBeforeRefreshing.Clear();
				}
				if (TriesCount >= 3)
				{
					Debug.Log((object)"[Better RNG] Recursion Prevented");
					TriesCount = 0;
					for (int n = 0; n < list.Count; n++)
					{
						ListOfStablePerksSeen.Add(list[n].perk.id);
					}
					return;
				}
				int num3 = 0;
				List<string> list6 = new List<string>();
				foreach (App_PerkPage_Card item2 in list)
				{
					bool flag3 = list2.Contains(item2.perk.id);
					bool flag4 = list3.Contains(item2.perk.id);
					foreach (KeyValuePair<string, int> item3 in dictionary)
					{
						if (item3.Value == num && item2.perk.id == item3.Key)
						{
							flag2 = true;
						}
					}
					if (list5.Count > 0 && num - num2 >= 10)
					{
						List<Perk> list7 = list5.Where((Perk p) => p.cost > 0).ToList();
						List<Perk> list8 = list5.Where((Perk p) => p.cost <= 0).ToList();
						Debug.Log((object)"[Better RNG] Triggered force spawn");
						if (list8.Count > 0)
						{
							Perk val6 = null;
							Perk val7 = null;
							val6 = list8[Random.Range(0, list8.Count)];
							list8.Remove(val6);
							CardReplacement.ReplaceCards(__instance, 0, val6, ListOfStablePerksSeen);
							if (list8.Count >= 1 && (Object)(object)list[2] != (Object)null)
							{
								val7 = list8[Random.Range(0, list8.Count)];
								CardReplacement.ReplaceCards(__instance, 1, val7, ListOfStablePerksSeen);
							}
						}
						if (list7.Count > 0)
						{
							Perk perk = list7[Random.Range(0, list7.Count)];
							if ((Object)(object)list[2] != (Object)null)
							{
								CardReplacement.ReplaceCards(__instance, 2, perk, ListOfStablePerksSeen);
							}
							else
							{
								CardReplacement.ReplaceCards(__instance, 1, perk, ListOfStablePerksSeen);
							}
						}
						val3 = list[0];
						for (int num4 = 0; num4 < list.Count; num4++)
						{
							App_PerkPage_Card val8 = list[num4];
							if (num4 == 0)
							{
								val8.SelectCard();
							}
							else
							{
								val8.DeselectCard();
							}
							val8.UpdateCard();
						}
						for (int num5 = 0; num5 < list.Count; num5++)
						{
							ListOfStablePerksSeen.Add(list[num5].perk.id);
						}
						return;
					}
					if (flag3)
					{
						TriesCount = 0;
						for (int num6 = 0; num6 < list.Count; num6++)
						{
							ListOfStablePerksSeen.Add(list[num6].perk.id);
						}
						return;
					}
					if (flag4)
					{
						num3++;
						list6.Add(item2.perk.id);
					}
					if (num3 >= 2)
					{
						Debug.Log((object)("[Better RNG] " + list6[0] + " and " + list6[1] + " matches unloved perks. We're done here."));
						TriesCount = 0;
						for (int num7 = 0; num7 < list.Count; num7++)
						{
							ListOfStablePerksSeen.Add(list[num7].perk.id);
						}
						return;
					}
				}
				if (flag2)
				{
					TriesCount++;
					if (refresh)
					{
						if (TriesCount == 1 && ListOfCardsBeforeRefreshing.Count == 0)
						{
							Debug.Log((object)"[Better RNG] User is refreshing, saving current cards to static list in case more rerolls are needed.");
							for (int num8 = 0; num8 < list.Count; num8++)
							{
								ListOfCardsBeforeRefreshing.Add(list[num8].perk);
							}
						}
						else
						{
							Debug.Log((object)"[Better RNG] Reroll was performed after refresh, setting cards to original list to prevent dupes.");
							int num9 = 0;
							foreach (Perk item4 in ListOfCardsBeforeRefreshing)
							{
								CardReplacement.ReplaceCards(__instance, num9, item4, null);
								num9++;
							}
						}
						val5.Method("GenerateCards", new object[1] { true }).GetValue();
					}
					else
					{
						val5.Method("GenerateCards", new object[1] { false }).GetValue();
					}
				}
				else
				{
					Debug.Log((object)"[Better RNG] All good buddy :)");
					for (int num10 = 0; num10 < list.Count; num10++)
					{
						ListOfStablePerksSeen.Add(list[num10].perk.id);
					}
					TriesCount = 0;
				}
			}
			else
			{
				UnstableRNG.EverythingElse(__instance);
			}
		}
	}
	public static class ArtifactState
	{
		public static int CycleCount;

		public static List<Item> ListOfArtifacts = new List<Item>();

		public static List<int> order = new List<int>();

		public static bool began;

		public static void Reset()
		{
			CycleCount = 0;
			ListOfArtifacts.Clear();
			order.Clear();
			began = false;
		}
	}
	[HarmonyPatch(typeof(UT_AddItemsToPlayer), "AddItems")]
	internal class ArtifactRNG
	{
		private static bool Prefix()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_00b8: 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_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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: 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_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			Inventory inventory = ENT_Player.GetInventory();
			if (ArtifactState.ListOfArtifacts.Count == 0)
			{
				Item clone = CL_AssetManager.GetAssetGameObject("Item_Artifact_Rebar_Return", "").GetComponent<Item_Object>().itemData.GetClone();
				clone.bagPosition = new Vector3(0f, 0f, 1f) + Random.insideUnitSphere * 0.01f;
				clone.bagRotation = Quaternion.LookRotation(clone.upDirection);
				Item clone2 = CL_AssetManager.GetAssetGameObject("Item_Artifact_Remote", "").GetComponent<Item_Object>().itemData.GetClone();
				clone2.bagPosition = new Vector3(0f, 0f, 1f) + Random.insideUnitSphere * 0.01f;
				clone2.bagRotation = Quaternion.LookRotation(clone2.upDirection);
				Item clone3 = CL_AssetManager.GetAssetGameObject("Item_Artifact_Timepiece", "").GetComponent<Item_Object>().itemData.GetClone();
				clone3.bagPosition = new Vector3(0f, 0f, 1f) + Random.insideUnitSphere * 0.01f;
				clone3.bagRotation = Quaternion.LookRotation(clone3.upDirection);
				Item clone4 = CL_AssetManager.GetAssetGameObject("Item_Artifact_Translocator", "").GetComponent<Item_Object>().itemData.GetClone();
				clone4.bagPosition = new Vector3(0f, 0f, 1f) + Random.insideUnitSphere * 0.01f;
				clone4.bagRotation = Quaternion.LookRotation(clone4.upDirection);
				Item clone5 = CL_AssetManager.GetAssetGameObject("Item_Artifact_EVAGlove", "").GetComponent<Item_Object>().itemData.GetClone();
				clone5.bagPosition = new Vector3(0f, 0f, 1f) + Random.insideUnitSphere * 0.01f;
				clone5.bagRotation = Quaternion.LookRotation(clone5.upDirection);
				ArtifactState.ListOfArtifacts.Add(clone);
				ArtifactState.ListOfArtifacts.Add(clone2);
				ArtifactState.ListOfArtifacts.Add(clone3);
				ArtifactState.ListOfArtifacts.Add(clone4);
				ArtifactState.ListOfArtifacts.Add(clone5);
			}
			if (ArtifactState.CycleCount == 5 || !ArtifactState.began || ArtifactState.order.Count() == 0)
			{
				ArtifactState.CycleCount = 0;
				ArtifactState.began = true;
				ArtifactState.order.Clear();
				ArtifactState.order = Enumerable.Range(0, ArtifactState.ListOfArtifacts.Count).ToList();
				for (int num = ArtifactState.order.Count - 1; num > 0; num--)
				{
					int num2 = Random.Range(0, num + 1);
					List<int> order = ArtifactState.order;
					int index = num;
					List<int> order2 = ArtifactState.order;
					int index2 = num2;
					int value = ArtifactState.order[num2];
					int value2 = ArtifactState.order[num];
					order[index] = value;
					order2[index2] = value2;
				}
			}
			if ((Object)(object)ENT_Player.GetInventory() != (Object)null)
			{
				List<Item> list = new List<Item>();
				list.Add(ArtifactState.ListOfArtifacts[ArtifactState.order[ArtifactState.CycleCount]]);
				MethodInfo methodInfo = AccessTools.Method(typeof(Inventory), "LoadItemsIntoBag", (Type[])null, (Type[])null);
				methodInfo.Invoke(inventory, new object[1] { list });
				ArtifactState.CycleCount++;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(M_Gamemode), "Initialize")]
	internal class yaahItsRewindTime
	{
		private static int starter;

		private static void Postfix(M_Gamemode __instance)
		{
			Canvas val = Object.FindObjectOfType<Canvas>();
			string gamemodeName = __instance.gamemodeName;
			if (gamemodeName == " Chimney")
			{
				CardsRNG.chimneyFlag = true;
			}
			Debug.Log((object)(((Object)val).name ?? ""));
			ArtifactState.Reset();
			rhoInfo.rhoInit();
			CheckboxUIHelper.created = false;
			if (((Object)val).name == CheckboxUIHelper.foundCanvas || starter == 0)
			{
				CheckboxUIHelper.EnsureCreated();
				starter++;
			}
		}
	}
	internal class rhoInfo
	{
		public static bool rhoTrading = false;

		public static bool rhoTradingCap = false;

		public static Dictionary<Perk, int> LibraryOfSeenRhoPerks = new Dictionary<Perk, int>();

		public static Perk swift;

		public static Perk protection;

		public static Perk regeneration;

		public static Perk overwhelm;

		internal static void rhoInit()
		{
			List<Perk> perkAssets = CL_AssetManager.GetFullCombinedAssetDatabase().perkAssets;
			foreach (Perk item in perkAssets)
			{
				if (((Object)item).name == "Perk_Rho_Minor_Blessing_Swift")
				{
					swift = item;
				}
				else if (((Object)item).name == "Perk_Rho_Minor_Blessing_Protection")
				{
					protection = item;
				}
				else if (((Object)item).name == "Perk_Rho_Minor_Blessing_Regeneration")
				{
					regeneration = item;
				}
				else if (((Object)item).name == "Perk_Rho_Superior_Blessing_Overwhelm")
				{
					overwhelm = item;
				}
			}
			LibraryOfSeenRhoPerks[swift] = 0;
			LibraryOfSeenRhoPerks[protection] = 0;
			LibraryOfSeenRhoPerks[regeneration] = 0;
			LibraryOfSeenRhoPerks[overwhelm] = 0;
		}
	}
	[HarmonyPatch(typeof(ENV_RhoAltar), "Trade")]
	internal class rhoAltarFlag
	{
		private static void Prefix(ENV_RhoAltar __instance)
		{
			int num = (int)AccessTools.Field(typeof(ENV_RhoAltar), "currentValue").GetValue(__instance);
			Debug.Log((object)$"CurrentValue = {num}");
			rhoInfo.rhoTrading = true;
			if (rhoInfo.LibraryOfSeenRhoPerks[rhoInfo.swift] >= 5 && rhoInfo.LibraryOfSeenRhoPerks[rhoInfo.protection] >= 5 && rhoInfo.LibraryOfSeenRhoPerks[rhoInfo.regeneration] >= 5 && num >= 8 && num < 25)
			{
				rhoInfo.rhoTradingCap = true;
			}
			if (rhoInfo.LibraryOfSeenRhoPerks[rhoInfo.overwhelm] >= 2 && num > 24)
			{
				rhoInfo.rhoTradingCap = true;
			}
			ENT_Player playerObject = ENT_Player.playerObject;
			Debug.Log((object)"Listing Player Perks....");
			Debug.Log((object)"");
			Debug.Log((object)"");
			foreach (Perk perk in playerObject.perks)
			{
				Debug.Log((object)(perk.id ?? ""));
			}
			Debug.Log((object)"");
			Debug.Log((object)"");
			Debug.Log((object)"============");
		}
	}
	[HarmonyPatch(typeof(ENT_Player), "AddPerk", new Type[]
	{
		typeof(Perk),
		typeof(int)
	})]
	internal class playerTrading
	{
		private static void Prefix(ENT_Player __instance, ref Perk perk)
		{
			if (!rhoInfo.rhoTrading)
			{
				return;
			}
			if (rhoInfo.LibraryOfSeenRhoPerks[perk] < 5 && perk.id != "Perk_Rho_Superior_Blessing_Overwhelm")
			{
				rhoInfo.LibraryOfSeenRhoPerks[perk]++;
			}
			else if (rhoInfo.LibraryOfSeenRhoPerks[perk] < 2 && perk.id == "Perk_Rho_Superior_Blessing_Overwhelm")
			{
				rhoInfo.LibraryOfSeenRhoPerks[perk]++;
			}
			else if (perk.id != "Perk_Rho_Superior_Blessing_Overwhelm")
			{
				Debug.Log((object)"[Better RNG] Perk has been seen too many times. Going through reroll logic.");
				List<KeyValuePair<Perk, int>> list = rhoInfo.LibraryOfSeenRhoPerks.Where((KeyValuePair<Perk, int> kvp) => kvp.Value <= 4 && kvp.Key.id != "Perk_Rho_Superior_Blessing_Overwhelm").ToList();
				if (list.Count > 0)
				{
					perk = list[Random.Range(0, list.Count)].Key;
				}
				else
				{
					Debug.Log((object)"No more rho perks :(");
				}
			}
		}
	}
	[HarmonyPatch(typeof(ENV_RhoAltar), "Trade")]
	internal class rhoAltarFlags
	{
		private static void Finalizer()
		{
			rhoInfo.rhoTrading = false;
			rhoInfo.rhoTradingCap = false;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "better.rng";

		public const string PLUGIN_NAME = "better.rng";

		public const string PLUGIN_VERSION = "2.0.5";
	}
}