using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using Assets.Scripts.Inventory__Items__Pickups.Items;
using Assets.Scripts.Saves___Serialization.Progression.Achievements;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ChestLootOverride")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ae4eb2bca00af8a1c4407a3dade780d904d89265")]
[assembly: AssemblyProduct("ChestLootOverride")]
[assembly: AssemblyTitle("ChestLootOverride")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace ChestLootOverride
{
public class BuildItemConfig
{
public List<EItem> Alternatives { get; set; } = new List<EItem>();
public bool? SkipIfLegendary { get; set; }
public bool? SkipIfEpic { get; set; }
public bool? SkipIfRare { get; set; }
public bool? OrderRandomize { get; set; }
public List<EItem> SkipIfItem { get; set; } = new List<EItem>();
}
public class BuildConfig
{
public string Name { get; set; } = string.Empty;
public int RangeStart { get; set; }
public int RangeEnd { get; set; }
public bool OrderRandomize { get; set; }
public List<BuildItemConfig> Items { get; set; } = new List<BuildItemConfig>();
}
public class RunState
{
public Dictionary<int, BuildConfig> ChestBuilds { get; set; } = new Dictionary<int, BuildConfig>();
public string ActiveBuildName { get; set; }
public int RangeStart { get; set; }
public int RangeEnd { get; set; }
public Queue<BuildItemConfig> ItemQueue { get; set; } = new Queue<BuildItemConfig>();
public int CurrentChestIndex { get; set; }
public void Reset()
{
ChestBuilds.Clear();
ActiveBuildName = null;
RangeStart = 0;
RangeEnd = 0;
ItemQueue.Clear();
CurrentChestIndex = 0;
}
}
public class BuildUI : MonoBehaviour
{
private bool _showMenu;
private Vector2 _scrollPosition = Vector2.zero;
private Rect _menuRect = new Rect(100f, 100f, 500f, 600f);
private void Update()
{
if (Input.GetKeyDown((KeyCode)284))
{
_showMenu = !_showMenu;
}
}
private void OnGUI()
{
if (Plugin.Instance._enableMod.Value)
{
DrawOverlay();
if (_showMenu)
{
DrawMenu();
}
}
}
private void DrawOverlay()
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Expected O, but got Unknown
//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_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Expected O, but got Unknown
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
//IL_02b6: 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_02c1: Unknown result type (might be due to invalid IL or missing references)
//IL_02cd: Expected O, but got Unknown
//IL_02d7: 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_0178: Unknown result type (might be due to invalid IL or missing references)
//IL_0253: Unknown result type (might be due to invalid IL or missing references)
//IL_0261: Unknown result type (might be due to invalid IL or missing references)
//IL_0266: Unknown result type (might be due to invalid IL or missing references)
//IL_026c: Unknown result type (might be due to invalid IL or missing references)
//IL_0278: Expected O, but got Unknown
//IL_0282: Unknown result type (might be due to invalid IL or missing references)
//IL_01db: Unknown result type (might be due to invalid IL or missing references)
//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
//IL_020c: Unknown result type (might be due to invalid IL or missing references)
//IL_0211: Unknown result type (might be due to invalid IL or missing references)
//IL_0217: Unknown result type (might be due to invalid IL or missing references)
//IL_0223: Expected O, but got Unknown
//IL_022d: Unknown result type (might be due to invalid IL or missing references)
RunState currentRunState = Plugin.CurrentRunState;
if (string.IsNullOrEmpty(currentRunState.ActiveBuildName) && currentRunState.ItemQueue.Count == 0)
{
return;
}
GUIStyle val = new GUIStyle(GUI.skin.label)
{
fontSize = 16,
fontStyle = (FontStyle)1
};
val.normal.textColor = Color.white;
GUIStyle val2 = val;
GUIStyle val3 = new GUIStyle(GUI.skin.label)
{
fontSize = 16,
fontStyle = (FontStyle)1
};
val3.normal.textColor = Color.black;
GUIStyle val4 = val3;
float num = 10f;
float num2 = 510f;
float num3 = 25f;
float num4 = 2f;
if (!string.IsNullOrEmpty(currentRunState.ActiveBuildName))
{
string text = "Build: " + currentRunState.ActiveBuildName;
GUI.Label(new Rect(num + num4, num2 + num4, 400f, num3), text, val4);
GUI.Label(new Rect(num, num2, 400f, num3), text, val2);
num2 += num3;
}
if (currentRunState.RangeStart > 0 && currentRunState.RangeEnd > 0)
{
string text2 = $"Range: Chests {currentRunState.RangeStart}-{currentRunState.RangeEnd}";
GUI.Label(new Rect(num + num4, num2 + num4, 400f, num3), text2, val4);
GUI.Label(new Rect(num, num2, 400f, num3), text2, val2);
num2 += num3;
}
if (currentRunState.ItemQueue.Count > 0)
{
BuildItemConfig buildItemConfig = currentRunState.ItemQueue.Peek();
EItem? firstNonBannedItem = GetFirstNonBannedItem(buildItemConfig.Alternatives);
if (firstNonBannedItem.HasValue)
{
string text3 = $"Next: {firstNonBannedItem.Value}";
GUI.Label(new Rect(num + num4, num2 + num4, 400f, num3), text3, val4);
GUIStyle val5 = new GUIStyle(val2);
val5.normal.textColor = Color.yellow;
GUIStyle val6 = val5;
GUI.Label(new Rect(num, num2, 400f, num3), text3, val6);
}
else
{
string text4 = "Next: (All banned)";
GUI.Label(new Rect(num + num4, num2 + num4, 400f, num3), text4, val4);
GUIStyle val7 = new GUIStyle(val2);
val7.normal.textColor = Color.red;
GUIStyle val8 = val7;
GUI.Label(new Rect(num, num2, 400f, num3), text4, val8);
}
}
else
{
string text5 = "Next: (Queue empty)";
GUI.Label(new Rect(num + num4, num2 + num4, 400f, num3), text5, val4);
GUIStyle val9 = new GUIStyle(val2);
val9.normal.textColor = Color.gray;
GUIStyle val10 = val9;
GUI.Label(new Rect(num, num2, 400f, num3), text5, val10);
}
}
private void DrawMenu()
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: 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)
_menuRect = GUI.Window(0, _menuRect, WindowFunction.op_Implicit((Action<int>)DrawMenuWindow), "Build Queue Menu (F3 to close)");
}
private void DrawMenuWindow(int windowID)
{
//IL_0016: 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_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
//IL_0133: 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_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_014d: Expected O, but got Unknown
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: Unknown result type (might be due to invalid IL or missing references)
//IL_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_0198: Unknown result type (might be due to invalid IL or missing references)
//IL_01a8: Expected O, but got Unknown
//IL_036a: 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_0375: Unknown result type (might be due to invalid IL or missing references)
//IL_0385: Expected O, but got Unknown
//IL_0240: Unknown result type (might be due to invalid IL or missing references)
//IL_025b: Unknown result type (might be due to invalid IL or missing references)
//IL_0260: Unknown result type (might be due to invalid IL or missing references)
//IL_0266: Unknown result type (might be due to invalid IL or missing references)
//IL_0276: Expected O, but got Unknown
//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
//IL_02a6: 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_02bf: Unknown result type (might be due to invalid IL or missing references)
//IL_0336: Unknown result type (might be due to invalid IL or missing references)
//IL_033b: Unknown result type (might be due to invalid IL or missing references)
//IL_0341: Unknown result type (might be due to invalid IL or missing references)
//IL_034b: Unknown result type (might be due to invalid IL or missing references)
//IL_0359: Expected O, but got Unknown
RunState currentRunState = Plugin.CurrentRunState;
GUILayout.BeginVertical((Il2CppReferenceArray<GUILayoutOption>)null);
GUIStyle val = new GUIStyle(GUI.skin.label)
{
fontSize = 12,
fontStyle = (FontStyle)1
};
GUILayout.Label("Active Build: " + (string.IsNullOrEmpty(currentRunState.ActiveBuildName) ? "None" : currentRunState.ActiveBuildName), val, (Il2CppReferenceArray<GUILayoutOption>)null);
GUILayout.Label($"Range: Chests {currentRunState.RangeStart}-{currentRunState.RangeEnd}", val, (Il2CppReferenceArray<GUILayoutOption>)null);
GUILayout.Label($"Queue Size: {currentRunState.ItemQueue.Count}", val, (Il2CppReferenceArray<GUILayoutOption>)null);
GUILayout.Label($"Current Chest: {GetChestOpenCount()}", val, (Il2CppReferenceArray<GUILayoutOption>)null);
GUILayout.Label("", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(10f) });
GUILayout.Label("Item Queue:", new GUIStyle(GUI.skin.label)
{
fontSize = 14,
fontStyle = (FontStyle)1
}, (Il2CppReferenceArray<GUILayoutOption>)null);
_scrollPosition = GUILayout.BeginScrollView(_scrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(400f) });
if (currentRunState.ItemQueue.Count == 0)
{
GUIStyle val2 = new GUIStyle(GUI.skin.label);
val2.normal.textColor = Color.gray;
GUILayout.Label("Queue is empty", val2, (Il2CppReferenceArray<GUILayoutOption>)null);
}
else
{
int num = 1;
foreach (BuildItemConfig item in currentRunState.ItemQueue)
{
EItem? firstNonBannedItem = GetFirstNonBannedItem(item.Alternatives);
GUILayout.BeginHorizontal(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>());
GUILayout.Label($"{num}.", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) });
if (firstNonBannedItem.HasValue)
{
string obj = $"{firstNonBannedItem.Value}";
GUIStyle val3 = new GUIStyle(GUI.skin.label);
val3.normal.textColor = Color.white;
GUILayout.Label(obj, val3, (Il2CppReferenceArray<GUILayoutOption>)null);
if (item.Alternatives.Count > 1)
{
List<string> list = new List<string>();
foreach (EItem alternative in item.Alternatives)
{
EItem current2 = alternative;
if (IsItemBanned(current2))
{
list.Add($"{current2} (banned)");
}
else
{
list.Add(((object)(EItem)(ref current2)).ToString());
}
}
string text = string.Join(", ", list);
string text2 = "(" + text + ")";
GUIStyle val4 = new GUIStyle(GUI.skin.label);
val4.normal.textColor = Color.gray;
val4.fontSize = 11;
GUILayout.Label(text2, val4, (Il2CppReferenceArray<GUILayoutOption>)null);
}
}
else
{
GUIStyle val5 = new GUIStyle(GUI.skin.label);
val5.normal.textColor = Color.red;
GUILayout.Label("(All banned)", val5, (Il2CppReferenceArray<GUILayoutOption>)null);
}
GUILayout.EndHorizontal();
num++;
}
}
GUILayout.EndScrollView();
GUILayout.Label("", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(10f) });
if (GUILayout.Button("Close (F3)", Array.Empty<GUILayoutOption>()))
{
_showMenu = false;
}
GUILayout.EndVertical();
GUI.DragWindow();
}
private EItem? GetFirstNonBannedItem(List<EItem> alternatives)
{
//IL_000b: 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_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
foreach (EItem alternative in alternatives)
{
if (!IsItemBanned(alternative))
{
return alternative;
}
}
return null;
}
private bool IsItemBanned(EItem item)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected I4, but got Unknown
if (Plugin.BannedItems != null)
{
return Plugin.BannedItems.Contains((int)item);
}
return false;
}
private int GetChestOpenCount()
{
return Plugin.GetChestOpenCount();
}
}
internal static class ItemBuildConfigExtensions
{
private static ManualLogSource Log = ((BasePlugin)Plugin.Instance).Log;
public static BuildConfig LoadBuild(this ConfigFile Config, int buildNumber)
{
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Expected O, but got Unknown
//IL_0196: Unknown result type (might be due to invalid IL or missing references)
//IL_019d: Expected O, but got Unknown
//IL_0804: Unknown result type (might be due to invalid IL or missing references)
//IL_080b: Expected O, but got Unknown
//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
//IL_03ad: Expected O, but got Unknown
//IL_0393: Unknown result type (might be due to invalid IL or missing references)
//IL_07b4: Unknown result type (might be due to invalid IL or missing references)
BuildConfig buildConfig = new BuildConfig();
ConfigEntry<string> val = Config.Bind<string>("Builds", $"Build{buildNumber}Name", "", $"Name for build {buildNumber}");
buildConfig.Name = val.Value;
ConfigEntry<string> val2 = Config.Bind<string>("Builds", $"Build{buildNumber}Range", "", $"Range for build {buildNumber}");
bool flag = default(bool);
if (string.IsNullOrWhiteSpace(val2.Value))
{
ManualLogSource log = Log;
BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Build ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(buildNumber);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" has no range specified, skipping");
}
log.LogWarning(val3);
return null;
}
string[] array = val2.Value.Split('-');
if (array.Length != 2 || !int.TryParse(array[0].Trim(), out var result) || !int.TryParse(array[1].Trim(), out var result2))
{
ManualLogSource log2 = Log;
BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(33, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Build ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(buildNumber);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" has invalid range format: ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(val2.Value);
}
log2.LogWarning(val3);
return null;
}
buildConfig.RangeStart = result;
buildConfig.RangeEnd = result2;
ConfigEntry<bool> val4 = Config.Bind<bool>("Builds", $"Build{buildNumber}OrderRandomize", false, $"Randomize order for build {buildNumber}");
buildConfig.OrderRandomize = val4.Value;
int itemIndex = 1;
while (true)
{
ConfigEntry<string> val5 = Config.Bind<string>("Builds", $"Build{buildNumber}Item{itemIndex}", "", $"Item {itemIndex} for build {buildNumber}");
if (string.IsNullOrWhiteSpace(val5.Value))
{
break;
}
BuildItemConfig buildItemConfig = new BuildItemConfig();
if (val5.Value.Trim().Equals("EMPTY", StringComparison.OrdinalIgnoreCase))
{
buildConfig.Items.Add(buildItemConfig);
itemIndex++;
continue;
}
string[] array2 = val5.Value.Split('|');
for (int i = 0; i < array2.Length; i++)
{
string text = array2[i].Trim();
if (Enum.TryParse<EItem>(text, ignoreCase: true, out EItem result3))
{
buildItemConfig.Alternatives.Add(result3);
continue;
}
ManualLogSource log3 = Log;
BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(33, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Build ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(buildNumber);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" Item");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(itemIndex);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": Invalid item name '");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'");
}
log3.LogWarning(val3);
}
if (buildItemConfig.Alternatives.Count > 0)
{
ConfigEntry<bool> val6 = Config.Bind<bool>("Builds", $"Build{buildNumber}Item{itemIndex}SkipIfLegendary", false, $"Skip if Legendary for build {buildNumber} item {itemIndex}");
if (Config.Keys.Any((ConfigDefinition k) => k.Section == "Builds" && k.Key == $"Build{buildNumber}Item{itemIndex}SkipIfLegendary"))
{
buildItemConfig.SkipIfLegendary = val6.Value;
}
ConfigEntry<bool> val7 = Config.Bind<bool>("Builds", $"Build{buildNumber}Item{itemIndex}SkipIfEpic", false, $"Skip if Epic for build {buildNumber} item {itemIndex}");
if (Config.Keys.Any((ConfigDefinition k) => k.Section == "Builds" && k.Key == $"Build{buildNumber}Item{itemIndex}SkipIfEpic"))
{
buildItemConfig.SkipIfEpic = val7.Value;
}
ConfigEntry<bool> val8 = Config.Bind<bool>("Builds", $"Build{buildNumber}Item{itemIndex}SkipIfRare", false, $"Skip if Rare for build {buildNumber} item {itemIndex}");
if (Config.Keys.Any((ConfigDefinition k) => k.Section == "Builds" && k.Key == $"Build{buildNumber}Item{itemIndex}SkipIfRare"))
{
buildItemConfig.SkipIfRare = val8.Value;
}
ConfigEntry<string> val9 = Config.Bind<string>("Builds", $"Build{buildNumber}Item{itemIndex}SkipIfItem", "", $"Skip if item matches for build {buildNumber} item {itemIndex}");
if (!string.IsNullOrWhiteSpace(val9.Value))
{
array2 = val9.Value.Split(',');
for (int i = 0; i < array2.Length; i++)
{
if (Enum.TryParse<EItem>(array2[i].Trim(), ignoreCase: true, out EItem result4))
{
buildItemConfig.SkipIfItem.Add(result4);
}
}
}
buildConfig.Items.Add(buildItemConfig);
}
itemIndex++;
}
if (buildConfig.Items.Count == 0)
{
ManualLogSource log4 = Log;
BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Build ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(buildNumber);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" has no items, skipping");
}
log4.LogWarning(val3);
return null;
}
return buildConfig;
}
public static void SaveBuildToConfig(this ConfigFile Config, int buildNumber, BuildConfig build)
{
Config.Bind<string>("Builds", $"Build{buildNumber}Name", build.Name, $"Name for build {buildNumber}").Value = build.Name;
Config.Bind<string>("Builds", $"Build{buildNumber}Range", $"{build.RangeStart}-{build.RangeEnd}", $"Range for build {buildNumber}").Value = $"{build.RangeStart}-{build.RangeEnd}";
Config.Bind<bool>("Builds", $"Build{buildNumber}OrderRandomize", build.OrderRandomize, $"Randomize order for build {buildNumber}").Value = build.OrderRandomize;
for (int i = 0; i < build.Items.Count; i++)
{
BuildItemConfig buildItemConfig = build.Items[i];
int value = i + 1;
string text = ((buildItemConfig.Alternatives.Count == 0) ? "EMPTY" : string.Join("|", buildItemConfig.Alternatives.Select((EItem item) => ((object)(EItem)(ref item)).ToString())));
Config.Bind<string>("Builds", $"Build{buildNumber}Item{value}", text, $"Item {value} for build {buildNumber}").Value = text;
if (buildItemConfig.SkipIfLegendary.HasValue && buildItemConfig.SkipIfLegendary.Value)
{
Config.Bind<bool>("Builds", $"Build{buildNumber}Item{value}SkipIfLegendary", buildItemConfig.SkipIfLegendary.Value, $"Skip if Legendary for build {buildNumber} item {value}").Value = buildItemConfig.SkipIfLegendary.Value;
}
if (buildItemConfig.SkipIfEpic.HasValue && buildItemConfig.SkipIfEpic.Value)
{
Config.Bind<bool>("Builds", $"Build{buildNumber}Item{value}SkipIfEpic", buildItemConfig.SkipIfEpic.Value, $"Skip if Epic for build {buildNumber} item {value}").Value = buildItemConfig.SkipIfEpic.Value;
}
if (buildItemConfig.SkipIfRare.HasValue && buildItemConfig.SkipIfRare.Value)
{
Config.Bind<bool>("Builds", $"Build{buildNumber}Item{value}SkipIfRare", buildItemConfig.SkipIfRare.Value, $"Skip if Rare for build {buildNumber} item {value}").Value = buildItemConfig.SkipIfRare.Value;
}
if (buildItemConfig.SkipIfItem != null && buildItemConfig.SkipIfItem.Count > 0)
{
string text2 = string.Join(", ", buildItemConfig.SkipIfItem.Select((EItem item) => ((object)(EItem)(ref item)).ToString()));
Config.Bind<string>("Builds", $"Build{buildNumber}Item{value}SkipIfItem", text2, $"Skip if item matches for build {buildNumber} item {value}").Value = text2;
}
}
}
}
[BepInPlugin("com.Rofliex.ChestLootOverride", "ChestLootOverride", "3.0.0")]
public class Plugin : BasePlugin
{
[HarmonyPatch(typeof(ItemInventory), "AddItem", new Type[] { typeof(EItem) })]
public static class ItemInventoryAddItem1Patch
{
[HarmonyPrefix]
public static bool Prefix(ItemInventory __instance, ref EItem eItem)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected I4, but got Unknown
if (!Instance._enableMod.Value)
{
return true;
}
if (_itemToReplace.HasValue)
{
eItem = (EItem)(int)_itemToReplace.Value;
}
_itemToReplace = null;
return true;
}
}
[HarmonyPatch(typeof(ItemInventory), "AddItem", new Type[]
{
typeof(EItem),
typeof(int)
})]
public static class ItemInventoryAddItem2Patch
{
[HarmonyPrefix]
public static bool Prefix(ItemInventory __instance, ref EItem eItem, ref int count)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected I4, but got Unknown
if (!Instance._enableMod.Value)
{
return true;
}
if (_itemToReplace.HasValue)
{
eItem = (EItem)(int)_itemToReplace.Value;
}
_itemToReplace = null;
return true;
}
}
[HarmonyPatch(typeof(ChestOpening), "OpenChest")]
public static class ChestLootPatch
{
[HarmonyPrefix]
public static bool Prefix(ChestOpening __instance, ref ItemData itemData)
{
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: 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_015e: 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_01c1: Unknown result type (might be due to invalid IL or missing references)
if (!Instance._enableMod.Value)
{
return true;
}
_itemToReplace = null;
try
{
if (!CurrentRunState.ChestBuilds.TryGetValue(_chestOpenCount, out var value))
{
return true;
}
if (!(CurrentRunState.ActiveBuildName == value.Name) || _chestOpenCount < CurrentRunState.RangeStart || _chestOpenCount > CurrentRunState.RangeEnd)
{
ApplyBuildToRunState(value);
}
if (CurrentRunState.ItemQueue.Count == 0)
{
return true;
}
BuildItemConfig buildItemConfig = CurrentRunState.ItemQueue.Peek();
EItem? firstNonBannedItem = GetFirstNonBannedItem(buildItemConfig.Alternatives);
if (!firstNonBannedItem.HasValue)
{
CurrentRunState.ItemQueue.Dequeue();
return true;
}
if (ShouldSkipReplacement(buildItemConfig, itemData))
{
CurrentRunState.ItemQueue.Dequeue();
CurrentRunState.ItemQueue.Enqueue(buildItemConfig);
return true;
}
ItemData item = DataManager.Instance.GetItem(firstNonBannedItem.Value);
if ((Object)(object)item == (Object)null)
{
CurrentRunState.ItemQueue.Dequeue();
return true;
}
if (itemData.eItem != firstNonBannedItem.Value)
{
itemData = item;
__instance.itemData = item;
_itemToReplace = item.eItem;
ChestWindowUi val = Object.FindObjectOfType<ChestWindowUi>();
if ((Object)(object)val != (Object)null)
{
val.itemData = item;
((TMP_Text)val.t_itemDesc).text = ((Object)((UnlockableBase)item).localizedDescription).ToString();
((TMP_Text)val.t_itemName).text = ((Object)((UnlockableBase)item).localizedName).ToString();
TextMeshProUGUI t_itemRarity = val.t_itemRarity;
EItemRarity rarity = item.rarity;
((TMP_Text)t_itemRarity).text = ((object)(EItemRarity)(ref rarity)).ToString();
}
}
CurrentRunState.ItemQueue.Dequeue();
}
catch (Exception)
{
}
return true;
}
}
public const string PluginGuid = "com.Rofliex.ChestLootOverride";
public const string PluginName = "ChestLootOverride";
public const string PluginVersion = "3.0.0";
public static List<int> BannedItems;
public static Plugin Instance;
private static List<BuildConfig> _builds = new List<BuildConfig>();
private static int _chestOpenCount = 0;
private static bool _isSavingDefaultBuilds = false;
private Harmony _harmony;
public ConfigEntry<bool> _enableMod;
private static EItem? _itemToReplace = null;
private BuildUI _uiGameObject;
public static RunState CurrentRunState { get; private set; } = new RunState();
public static int GetChestOpenCount()
{
return _chestOpenCount;
}
public override void Load()
{
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Expected O, but got Unknown
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Expected O, but got Unknown
Instance = this;
_enableMod = ((BasePlugin)this).Config.Bind<bool>("General", "EnableMod", true, "Enable/disable the mod");
((BasePlugin)this).Config.SettingChanged += OnConfigOnSettingChanged;
LoadBuildsFromConfig();
ChestOpening.A_ChestFinished += Action<ItemData>.op_Implicit((Action<ItemData>)OnChestFinished);
GameManager.A_RunStarted += Action.op_Implicit((Action)delegate
{
_chestOpenCount = 1;
_itemToReplace = null;
CurrentRunState.Reset();
SelectBuildsForRun();
});
_harmony = new Harmony("com.Rofliex.ChestLootOverride");
try
{
_harmony.PatchAll();
}
catch (Exception ex)
{
ManualLogSource log = ((BasePlugin)this).Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Error applying patches: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
log.LogError(val);
}
InitializeUI();
static void OnChestFinished(ItemData itemData)
{
_chestOpenCount++;
}
}
private void InitializeUI()
{
ClassInjector.RegisterTypeInIl2Cpp<BuildUI>();
_uiGameObject = ((BasePlugin)this).AddComponent<BuildUI>();
Object.DontDestroyOnLoad((Object)(object)_uiGameObject);
}
private void OnConfigOnSettingChanged(object o, SettingChangedEventArgs settingChangedEventArgs)
{
if (!_isSavingDefaultBuilds)
{
LoadBuildsFromConfig();
}
}
private void LoadBuildsFromConfig()
{
_builds.Clear();
Regex regex = new Regex("^Build(\\d+)(\\w+)$", RegexOptions.IgnoreCase);
List<ConfigDefinition> list = ((BasePlugin)this).Config.Keys.Where((ConfigDefinition key) => key.Section == "Builds").ToList();
HashSet<int> hashSet = new HashSet<int>();
foreach (ConfigDefinition item in list)
{
Match match = regex.Match(item.Key);
if (match.Success && int.TryParse(match.Groups[1].Value, out var result))
{
hashSet.Add(result);
}
}
foreach (int item2 in hashSet.OrderBy((int x) => x))
{
BuildConfig buildConfig = ((BasePlugin)this).Config.LoadBuild(item2);
if (buildConfig != null)
{
_builds.Add(buildConfig);
}
}
if (_builds.Count == 0)
{
CreateDefaultBuild();
}
}
private void CreateDefaultBuild()
{
BuildConfig buildConfig = new BuildConfig
{
Name = "EarlyBuild1",
OrderRandomize = true,
Items = new List<BuildItemConfig>(5)
{
new BuildItemConfig
{
Alternatives = new List<EItem>(2)
{
(EItem)43,
(EItem)13
}
},
new BuildItemConfig
{
Alternatives = new List<EItem>(2)
{
(EItem)32,
(EItem)75
}
},
new BuildItemConfig
{
Alternatives = new List<EItem>(3)
{
(EItem)47,
(EItem)46,
(EItem)29
}
},
new BuildItemConfig
{
Alternatives = new List<EItem>(1) { (EItem)0 }
},
new BuildItemConfig
{
Alternatives = new List<EItem>(1) { (EItem)64 }
}
},
RangeStart = 1,
RangeEnd = 5
};
BuildConfig buildConfig2 = new BuildConfig
{
Name = "EarlyBuild2",
OrderRandomize = true,
Items = new List<BuildItemConfig>(5)
{
new BuildItemConfig
{
Alternatives = new List<EItem>(1) { (EItem)13 }
},
new BuildItemConfig
{
Alternatives = new List<EItem>(1) { (EItem)73 }
},
new BuildItemConfig
{
Alternatives = new List<EItem>(2)
{
(EItem)28,
(EItem)46
}
},
new BuildItemConfig
{
Alternatives = new List<EItem>(1) { (EItem)0 }
},
new BuildItemConfig
{
Alternatives = new List<EItem>(1) { (EItem)64 }
}
},
RangeStart = 1,
RangeEnd = 5
};
BuildConfig buildConfig3 = new BuildConfig
{
Name = "MidBuild1",
OrderRandomize = true,
Items = new List<BuildItemConfig>(4)
{
new BuildItemConfig
{
Alternatives = new List<EItem>
{
(EItem)41,
(EItem)15,
(EItem)18
},
OrderRandomize = true
},
new BuildItemConfig
{
Alternatives = new List<EItem>(2)
{
(EItem)11,
(EItem)29
}
},
new BuildItemConfig
{
Alternatives = new List<EItem>(1) { (EItem)0 }
},
new BuildItemConfig
{
Alternatives = new List<EItem>(1) { (EItem)33 }
}
},
RangeStart = 6,
RangeEnd = 10
};
BuildConfig buildConfig4 = new BuildConfig
{
Name = "EndBuild1",
OrderRandomize = true,
Items = new List<BuildItemConfig>(3)
{
new BuildItemConfig
{
Alternatives = new List<EItem>(1) { (EItem)26 }
},
new BuildItemConfig
{
Alternatives = new List<EItem>()
},
new BuildItemConfig
{
Alternatives = new List<EItem>()
}
},
RangeStart = 18,
RangeEnd = 20
};
_builds.Add(buildConfig);
_builds.Add(buildConfig2);
_builds.Add(buildConfig3);
_builds.Add(buildConfig4);
_isSavingDefaultBuilds = true;
try
{
((BasePlugin)this).Config.SaveBuildToConfig(1, buildConfig);
((BasePlugin)this).Config.SaveBuildToConfig(2, buildConfig2);
((BasePlugin)this).Config.SaveBuildToConfig(3, buildConfig3);
((BasePlugin)this).Config.SaveBuildToConfig(4, buildConfig4);
}
finally
{
_isSavingDefaultBuilds = false;
}
}
private static bool IsItemBanned(EItem item)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected I4, but got Unknown
if (BannedItems != null)
{
return BannedItems.Contains((int)item);
}
return false;
}
private static EItem? GetFirstNonBannedItem(List<EItem> alternatives)
{
//IL_000b: 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_0011: 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)
foreach (EItem alternative in alternatives)
{
if (!IsItemBanned(alternative))
{
return alternative;
}
}
return null;
}
private static bool IsBuildValid(BuildConfig build)
{
bool result = false;
foreach (BuildItemConfig item in build.Items)
{
if (item.Alternatives.Count != 0 && GetFirstNonBannedItem(item.Alternatives).HasValue)
{
result = true;
}
}
return result;
}
private static BuildConfig SelectBuildForRange(int chestNumber)
{
List<BuildConfig> list = _builds.Where((BuildConfig b) => chestNumber >= b.RangeStart && chestNumber <= b.RangeEnd).Where(IsBuildValid).ToList();
if (list.Count == 0)
{
return null;
}
return list[Random.Shared.Next(list.Count)];
}
private static void SelectBuildsForRun()
{
foreach (int item in (from x in _builds.SelectMany(CollectionSelector).Distinct()
orderby x
select x).ToList())
{
BuildConfig buildConfig = SelectBuildForRange(item);
if (buildConfig != null)
{
CurrentRunState.ChestBuilds[item] = buildConfig;
}
}
static IEnumerable<int> CollectionSelector(BuildConfig b)
{
return Enumerable.Range(b.RangeStart, b.RangeEnd - b.RangeStart + 1);
}
}
private static void ApplyBuildToRunState(BuildConfig build)
{
CurrentRunState.ActiveBuildName = build.Name;
CurrentRunState.RangeStart = build.RangeStart;
CurrentRunState.RangeEnd = build.RangeEnd;
CurrentRunState.ItemQueue.Clear();
List<BuildItemConfig> list = build.Items.ToList();
if (build.OrderRandomize)
{
list = list.OrderBy((BuildItemConfig x) => Random.Shared.Next()).ToList();
}
foreach (BuildItemConfig item in list)
{
if (GetFirstNonBannedItem(item.OrderRandomize.GetValueOrDefault() ? item.Alternatives.OrderBy((EItem x) => Random.Shared.Next()).ToList() : item.Alternatives).HasValue)
{
CurrentRunState.ItemQueue.Enqueue(item);
}
}
}
private static bool ShouldSkipReplacement(BuildItemConfig itemConfig, ItemData originalItem)
{
//IL_0006: 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)
//IL_0033: Invalid comparison between Unknown and I4
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Invalid comparison between Unknown and I4
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Invalid comparison between Unknown and I4
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
ItemData item = DataManager.Instance.GetItem(originalItem.eItem);
if ((Object)(object)item == (Object)null)
{
return false;
}
if (itemConfig.SkipIfLegendary.GetValueOrDefault() && (int)item.rarity == 3)
{
return true;
}
if (itemConfig.SkipIfEpic.GetValueOrDefault() && (int)item.rarity == 2)
{
return true;
}
if (itemConfig.SkipIfRare.GetValueOrDefault() && (int)item.rarity == 1)
{
return true;
}
if (itemConfig.SkipIfItem.Count > 0 && itemConfig.SkipIfItem.Contains(originalItem.eItem))
{
return true;
}
return false;
}
}
}