Decompiled source of PeakRandomizedChaos v1.1.5
PeakRandomizedChaos.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.SceneManagement; using Zorro.Core; using Zorro.Core.Serizalization; using pworld.Scripts.Extensions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("MMHOOK_Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("PeakRandomizedChaos")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.1.5.0")] [assembly: AssemblyInformationalVersion("1.1.5")] [assembly: AssemblyProduct("PeakRandomizedChaos")] [assembly: AssemblyTitle("PeakRandomizedChaos")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace PeakRandomizedChaos { [BepInPlugin("PeakRandomizedChaos", "Chaos", "1.1.5")] public sealed class Plugin : BaseUnityPlugin { public const string ModGuid = "PeakRandomizedChaos"; public const string ModName = "Chaos"; public const string ModVersion = "1.1.5"; internal static ManualLogSource Log; internal static Plugin Instance; private Harmony _harmony = null; private bool _showSettingsGUI; private Rect _settingsWindowRect = new Rect(0f, 0f, 540f, 620f); private Vector2 _scrollPosition; private string _tempWaitTimeMin = ""; private string _tempWaitTimeMax = ""; private GUIStyle _buttonStyle = null; private GUIStyle _windowStyle = null; private GUIStyle _labelStyle = null; private GUIStyle _titleStyle = null; private GUIStyle _sectionStyle = null; private GUIStyle _textFieldStyle = null; private GUIStyle _textFieldHoverStyle = null; private GUIStyle _switchOnStyle = null; private GUIStyle _switchOffStyle = null; private GUIStyle _closeStyle = null; private GUIStyle _hintStyle = null; private Texture2D _btnTex = null; private Texture2D _btnHoverTex = null; private Texture2D _windowTex = null; private Texture2D _fieldTex = null; private Texture2D _accentTex = null; private Texture2D _rowTex = null; private Texture2D _switchOnTex = null; private Texture2D _switchOnHoverTex = null; private Texture2D _switchOffTex = null; private Texture2D _switchOffHoverTex = null; private Texture2D _dimTex = null; private bool _lastChaosMasterState; private bool _lastRandomEventsState; private void Awake() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; ModConfig.Startup(((BaseUnityPlugin)this).Config); _harmony = new Harmony("PeakRandomizedChaos"); _harmony.PatchAll(typeof(LootTablePatch)); _harmony.PatchAll(typeof(GameHandlerPatch)); _harmony.PatchAll(typeof(MountainProgressHandlerPatch)); _harmony.PatchAll(typeof(LoadingScreenHandlerPatch)); _harmony.PatchAll(typeof(PauseMenuMainPagePatch)); _harmony.PatchAll(typeof(AchievementManagerPatch)); _harmony.PatchAll(typeof(SpecialHeldItemPatch)); _harmony.PatchAll(typeof(RescueHookDestroyPatch)); _harmony.PatchAll(typeof(DayNightManagerBootstrapPatch)); _harmony.PatchAll(typeof(WindChillZonePatch)); _harmony.PatchAll(typeof(HotSunPatch)); _harmony.PatchAll(typeof(TornadoCompatibilityPatch)); _harmony.PatchAll(typeof(ItemOptimizationCompatibilityPatch)); SyncTempValuesFromConfig(); _lastChaosMasterState = ModConfig.EnableChaosMaster.Value; _lastRandomEventsState = ModConfig.EnableRandomEvents.Value; Log.LogInfo((object)"Chaos loaded."); } private void Update() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(ModConfig.ToggleGuiKey.Value)) { _showSettingsGUI = !_showSettingsGUI; if (_showSettingsGUI) { SyncTempValuesFromConfig(); } } bool value = ModConfig.EnableChaosMaster.Value; bool value2 = ModConfig.EnableRandomEvents.Value; if (_lastChaosMasterState == value && _lastRandomEventsState == value2) { return; } _lastChaosMasterState = value; _lastRandomEventsState = value2; if (PhotonNetwork.IsMasterClient) { if (!value || !value2) { RandomEventTask.StopTask(); RandomizerEvents.ClearPendingQueues(); } else { RandomEventTask.StartTask(); } } } private void OnGUI() { EnsureGuiStyles(); DrawSettingsButton(); if (_showSettingsGUI) { DrawSettingsWindow(); } } private void OnDestroy() { try { ChaosEnvironmentController.ResetLocalState(); if (PhotonNetwork.IsMasterClient) { RandomEventTask.StopTask(); RandomizerEvents.ClearPendingQueues(); } Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch { } SafeDestroy(ref _btnTex); SafeDestroy(ref _btnHoverTex); SafeDestroy(ref _windowTex); SafeDestroy(ref _fieldTex); SafeDestroy(ref _accentTex); SafeDestroy(ref _rowTex); SafeDestroy(ref _switchOnTex); SafeDestroy(ref _switchOnHoverTex); SafeDestroy(ref _switchOffTex); SafeDestroy(ref _switchOffHoverTex); SafeDestroy(ref _dimTex); } private static bool IsNonGameplayScene(string sceneName) { if (string.IsNullOrWhiteSpace(sceneName)) { return true; } switch (sceneName.ToLowerInvariant()) { case "airport": case "mainmenu": case "title": case "pretitle": case "wilisland": return true; default: return false; } } public static bool IsGameplayScene() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; return !IsNonGameplayScene(name); } private void DrawSettingsButton() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.ShowSettingsButton.Value) { return; } float num = 40f; float num2 = (float)Screen.width - num - 14f; float num3 = Mathf.Max(10f, ModConfig.SettingsButtonTopOffset.Value); if (GUI.Button(new Rect(num2, num3, num, num), "⚙", _buttonStyle)) { _showSettingsGUI = !_showSettingsGUI; if (_showSettingsGUI) { SyncTempValuesFromConfig(); ((Rect)(ref _settingsWindowRect)).x = Mathf.Max(10f, num2 - 486f); ((Rect)(ref _settingsWindowRect)).y = Mathf.Min((float)Screen.height - ((Rect)(ref _settingsWindowRect)).height - 10f, num3 + 48f); } } } private void DrawSettingsWindow() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //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) GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)_dimTex); _settingsWindowRect = GUI.Window(987654, _settingsWindowRect, new WindowFunction(DrawSettingsWindowContents), "", _windowStyle); } private void DrawSettingsWindowContents(int id) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) float width = ((Rect)(ref _settingsWindowRect)).width; float height = ((Rect)(ref _settingsWindowRect)).height; GUI.DrawTexture(new Rect(0f, 0f, width, height), (Texture)(object)_windowTex); GUI.DrawTexture(new Rect(0f, 0f, width, 52f), (Texture)(object)_accentTex); GUI.Label(new Rect(16f, 11f, 360f, 30f), "Chaos Settings", _titleStyle); if (GUI.Button(new Rect(width - 46f, 11f, 30f, 30f), "X", _closeStyle)) { _showSettingsGUI = false; } Rect val = default(Rect); ((Rect)(ref val))..ctor(14f, 64f, width - 28f, height - 122f); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(0f, 0f, ((Rect)(ref val)).width - 18f, 660f); _scrollPosition = GUI.BeginScrollView(val, _scrollPosition, val2); float y = 0f; DrawSectionLabel("界面", ref y, ((Rect)(ref val2)).width); DrawToggleRow("显示右上角设置按钮", ref y, ((Rect)(ref val2)).width, ModConfig.ShowSettingsButton); DrawSectionLabel("主开关", ref y, ((Rect)(ref val2)).width); DrawToggleRow("Chaos Mod 总开关", ref y, ((Rect)(ref val2)).width, ModConfig.EnableChaosMaster); DrawSectionLabel("随机内容", ref y, ((Rect)(ref val2)).width); DrawToggleRow("随机箱子 / 随机掉落", ref y, ((Rect)(ref val2)).width, ModConfig.EnableItemRandomization); DrawToggleRow("随机事件", ref y, ((Rect)(ref val2)).width, ModConfig.EnableRandomEvents); DrawSectionLabel("随机事件时间范围", ref y, ((Rect)(ref val2)).width); DrawTextFieldRow("最小时间(秒)", ref y, ((Rect)(ref val2)).width, ref _tempWaitTimeMin, delegate(string value) { if (int.TryParse(value, out var result2)) { ModConfig.WaitTimeMin.Value = Mathf.Max(1, result2); ClampTimeRange(); ((BaseUnityPlugin)this).Config.Save(); SyncTempValuesFromConfig(); } }, delegate(int delta) { ModConfig.WaitTimeMin.Value = Mathf.Max(1, ModConfig.WaitTimeMin.Value + delta); ClampTimeRange(); ((BaseUnityPlugin)this).Config.Save(); SyncTempValuesFromConfig(); }); DrawTextFieldRow("最大时间(秒)", ref y, ((Rect)(ref val2)).width, ref _tempWaitTimeMax, delegate(string value) { if (int.TryParse(value, out var result)) { ModConfig.WaitTimeMax.Value = Mathf.Max(1, result); ClampTimeRange(); ((BaseUnityPlugin)this).Config.Save(); SyncTempValuesFromConfig(); } }, delegate(int delta) { ModConfig.WaitTimeMax.Value = Mathf.Max(1, ModConfig.WaitTimeMax.Value + delta); ClampTimeRange(); ((BaseUnityPlugin)this).Config.Save(); SyncTempValuesFromConfig(); }); GUI.DrawTexture(new Rect(12f, y, ((Rect)(ref val2)).width - 24f, 44f), (Texture)(object)_rowTex); GUI.Label(new Rect(24f, y + 11f, ((Rect)(ref val2)).width - 48f, 24f), $"当前范围:{ModConfig.WaitTimeMin.Value}s ~ {ModConfig.WaitTimeMax.Value}s", _labelStyle); y += 56f; DrawToggleRow("最后一关熔炉允许龙卷风", ref y, ((Rect)(ref val2)).width, ModConfig.EnableTornadoAtKiln); GUI.Label(new Rect(12f, y, ((Rect)(ref val2)).width - 24f, 78f), $"GUI 热键:{ModConfig.ToggleGuiKey.Value}\n" + "关闭总开关后,随机箱子和随机事件都会停止。\n关闭“随机箱子”只影响掉落;关闭“随机事件”只影响事件。\n晒伤 / 烈日持续时间已从界面隐藏,只保留在配置文件中。", _hintStyle); GUI.EndScrollView(); if (GUI.Button(new Rect(16f, height - 44f, 120f, 30f), "恢复默认", _buttonStyle)) { ResetSimpleDefaults(); SyncTempValuesFromConfig(); } if (GUI.Button(new Rect(width - 116f, height - 44f, 100f, 30f), "关闭", _buttonStyle)) { _showSettingsGUI = false; } GUI.DragWindow(new Rect(0f, 0f, width, 52f)); } private void DrawSectionLabel(string text, ref float y, float width) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) GUI.Label(new Rect(12f, y, width - 24f, 26f), text, _sectionStyle); y += 32f; } private void DrawToggleRow(string label, ref float y, float width, ConfigEntry<bool> entry) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) GUI.DrawTexture(new Rect(12f, y, width - 24f, 42f), (Texture)(object)_rowTex); GUI.Label(new Rect(24f, y + 9f, width - 160f, 24f), label, _labelStyle); Rect val = default(Rect); ((Rect)(ref val))..ctor(width - 118f, y + 5f, 82f, 32f); GUIStyle val2 = (entry.Value ? _switchOnStyle : _switchOffStyle); string text = (entry.Value ? "ON" : "OFF"); if (GUI.Button(val, text, val2)) { entry.Value = !entry.Value; ((BaseUnityPlugin)this).Config.Save(); } y += 50f; } private void DrawTextFieldRow(string label, ref float y, float width, ref string tempValue, Action<string> onChanged, Action<int> onStep, int step = 5) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) GUI.DrawTexture(new Rect(12f, y, width - 24f, 42f), (Texture)(object)_rowTex); GUI.Label(new Rect(24f, y + 9f, width - 230f, 24f), label, _labelStyle); Rect val = default(Rect); ((Rect)(ref val))..ctor(width - 196f, y + 6f, 32f, 28f); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(width - 158f, y + 6f, 94f, 28f); Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(width - 58f, y + 6f, 32f, 28f); if (GUI.Button(val, "-", _buttonStyle)) { onStep(-Mathf.Abs(step)); GUI.FocusControl((string)null); } GUIStyle val4 = (((Rect)(ref val2)).Contains(Event.current.mousePosition) ? _textFieldHoverStyle : _textFieldStyle); string text = GUI.TextField(val2, tempValue, val4); if (text != tempValue) { tempValue = text; onChanged(text); } if (GUI.Button(val3, "+", _buttonStyle)) { onStep(Mathf.Abs(step)); GUI.FocusControl((string)null); } y += 50f; } private void SyncTempValuesFromConfig() { _tempWaitTimeMin = ModConfig.WaitTimeMin.Value.ToString(); _tempWaitTimeMax = ModConfig.WaitTimeMax.Value.ToString(); } private void ResetSimpleDefaults() { ModConfig.ShowSettingsButton.Value = true; ModConfig.EnableChaosMaster.Value = true; ModConfig.EnableItemRandomization.Value = true; ModConfig.EnableRandomEvents.Value = true; ModConfig.EnableTornadoAtKiln.Value = false; ModConfig.WaitTimeMin.Value = 30; ModConfig.WaitTimeMax.Value = 60; ModConfig.MesaSunDurationMin.Value = 10; ModConfig.MesaSunDurationMax.Value = 30; ModConfig.TropicsRain.Value = 0; ModConfig.RootsWindRandom.Value = 0; ModConfig.AlpineSnowRandom.Value = 0; ModConfig.MesaSunRandom.Value = 0; ModConfig.PitonPatch.Value = 35; ModConfig.ChainCache.Value = 22; ModConfig.ToxicBounceShroom.Value = 28; ModConfig.LowGravityShroom.Value = 18; ModConfig.SleepySpores.Value = 12; ModConfig.FungusCloud.Value = 14; ClampTimeRange(); ClampSunDurationRange(); ((BaseUnityPlugin)this).Config.Save(); } private void ClampTimeRange() { if (ModConfig.WaitTimeMin.Value < 1) { ModConfig.WaitTimeMin.Value = 1; } if (ModConfig.WaitTimeMax.Value < ModConfig.WaitTimeMin.Value) { ModConfig.WaitTimeMax.Value = ModConfig.WaitTimeMin.Value; } } private void ClampSunDurationRange() { if (ModConfig.MesaSunDurationMin.Value < 1) { ModConfig.MesaSunDurationMin.Value = 1; } if (ModConfig.MesaSunDurationMax.Value < ModConfig.MesaSunDurationMin.Value) { ModConfig.MesaSunDurationMax.Value = ModConfig.MesaSunDurationMin.Value; } } private void EnsureGuiStyles() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_010f: 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_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: 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) //IL_01cb: Expected O, but got Unknown //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Expected O, but got Unknown //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Expected O, but got Unknown //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Expected O, but got Unknown //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Expected O, but got Unknown //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Expected O, but got Unknown //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Expected O, but got Unknown //IL_034c: 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_0379: Expected O, but got Unknown //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Expected O, but got Unknown //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Expected O, but got Unknown //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_047a: Expected O, but got Unknown //IL_0551: Unknown result type (might be due to invalid IL or missing references) //IL_057b: Unknown result type (might be due to invalid IL or missing references) //IL_05a5: Unknown result type (might be due to invalid IL or missing references) //IL_05cf: Unknown result type (might be due to invalid IL or missing references) //IL_05f9: Unknown result type (might be due to invalid IL or missing references) //IL_0623: Unknown result type (might be due to invalid IL or missing references) //IL_064d: Unknown result type (might be due to invalid IL or missing references) //IL_0677: Unknown result type (might be due to invalid IL or missing references) //IL_06a7: Unknown result type (might be due to invalid IL or missing references) //IL_06b1: Expected O, but got Unknown //IL_06bc: Unknown result type (might be due to invalid IL or missing references) //IL_06c6: Expected O, but got Unknown //IL_06ce: Unknown result type (might be due to invalid IL or missing references) //IL_06d8: Expected O, but got Unknown //IL_07b6: Unknown result type (might be due to invalid IL or missing references) //IL_07c8: Unknown result type (might be due to invalid IL or missing references) //IL_07da: Unknown result type (might be due to invalid IL or missing references) //IL_07ec: Unknown result type (might be due to invalid IL or missing references) //IL_07fe: Unknown result type (might be due to invalid IL or missing references) //IL_0810: Unknown result type (might be due to invalid IL or missing references) //IL_0822: Unknown result type (might be due to invalid IL or missing references) //IL_0834: Unknown result type (might be due to invalid IL or missing references) //IL_0846: Unknown result type (might be due to invalid IL or missing references) //IL_0850: Expected O, but got Unknown //IL_08a0: Unknown result type (might be due to invalid IL or missing references) //IL_08b6: Unknown result type (might be due to invalid IL or missing references) //IL_08cc: Unknown result type (might be due to invalid IL or missing references) //IL_0909: Unknown result type (might be due to invalid IL or missing references) //IL_0913: Expected O, but got Unknown //IL_091f: Unknown result type (might be due to invalid IL or missing references) //IL_0929: Expected O, but got Unknown //IL_0979: Unknown result type (might be due to invalid IL or missing references) //IL_098f: Unknown result type (might be due to invalid IL or missing references) //IL_09a5: Unknown result type (might be due to invalid IL or missing references) //IL_09e2: Unknown result type (might be due to invalid IL or missing references) //IL_09ec: Expected O, but got Unknown //IL_09f8: Unknown result type (might be due to invalid IL or missing references) //IL_0a02: Expected O, but got Unknown //IL_0a52: Unknown result type (might be due to invalid IL or missing references) //IL_0a68: Unknown result type (might be due to invalid IL or missing references) //IL_0a7e: Unknown result type (might be due to invalid IL or missing references) //IL_0abb: Unknown result type (might be due to invalid IL or missing references) //IL_0ac5: Expected O, but got Unknown if (_buttonStyle == null) { _btnTex = MakeTexture(2, 2, new Color(0.16f, 0.45f, 0.86f, 1f)); _btnHoverTex = MakeTexture(2, 2, new Color(0.1f, 0.35f, 0.75f, 1f)); _windowTex = MakeTexture(2, 2, new Color(0.97f, 0.98f, 1f, 1f)); _fieldTex = MakeTexture(2, 2, new Color(1f, 1f, 1f, 1f)); _accentTex = MakeTexture(2, 2, new Color(0.1f, 0.3f, 0.62f, 1f)); _rowTex = MakeTexture(2, 2, new Color(0.9f, 0.94f, 0.99f, 1f)); _switchOnTex = MakeTexture(2, 2, new Color(0.12f, 0.62f, 0.29f, 1f)); _switchOnHoverTex = MakeTexture(2, 2, new Color(0.08f, 0.54f, 0.24f, 1f)); _switchOffTex = MakeTexture(2, 2, new Color(0.42f, 0.48f, 0.56f, 1f)); _switchOffHoverTex = MakeTexture(2, 2, new Color(0.34f, 0.4f, 0.48f, 1f)); _dimTex = MakeTexture(2, 2, new Color(0f, 0f, 0f, 0.42f)); _buttonStyle = new GUIStyle(GUI.skin.button); _buttonStyle.normal.background = _btnTex; _buttonStyle.hover.background = _btnHoverTex; _buttonStyle.active.background = _btnHoverTex; _buttonStyle.normal.textColor = Color.white; _buttonStyle.hover.textColor = Color.white; _buttonStyle.active.textColor = Color.white; _buttonStyle.fontSize = 15; _buttonStyle.fontStyle = (FontStyle)1; _buttonStyle.alignment = (TextAnchor)4; _buttonStyle.border = new RectOffset(0, 0, 0, 0); _buttonStyle.padding = new RectOffset(8, 8, 4, 4); _windowStyle = new GUIStyle(GUI.skin.window); _windowStyle.normal.background = _windowTex; _windowStyle.onNormal.background = _windowTex; _windowStyle.border = new RectOffset(0, 0, 0, 0); _windowStyle.padding = new RectOffset(0, 0, 0, 0); _titleStyle = new GUIStyle(GUI.skin.label); _titleStyle.fontSize = 19; _titleStyle.fontStyle = (FontStyle)1; _titleStyle.normal.textColor = Color.white; _titleStyle.alignment = (TextAnchor)3; _sectionStyle = new GUIStyle(GUI.skin.label); _sectionStyle.fontSize = 16; _sectionStyle.fontStyle = (FontStyle)1; _sectionStyle.normal.textColor = new Color(0.08f, 0.24f, 0.48f, 1f); _labelStyle = new GUIStyle(GUI.skin.label); _labelStyle.fontSize = 15; _labelStyle.normal.textColor = new Color(0.12f, 0.18f, 0.26f, 1f); _labelStyle.alignment = (TextAnchor)3; _hintStyle = new GUIStyle(GUI.skin.label); _hintStyle.fontSize = 13; _hintStyle.normal.textColor = new Color(0.22f, 0.28f, 0.36f, 1f); _textFieldStyle = new GUIStyle(GUI.skin.textField); _textFieldStyle.normal.background = _fieldTex; _textFieldStyle.hover.background = _fieldTex; _textFieldStyle.focused.background = _fieldTex; _textFieldStyle.active.background = _fieldTex; _textFieldStyle.onNormal.background = _fieldTex; _textFieldStyle.onHover.background = _fieldTex; _textFieldStyle.onFocused.background = _fieldTex; _textFieldStyle.onActive.background = _fieldTex; _textFieldStyle.normal.textColor = new Color(0.1f, 0.14f, 0.2f, 1f); _textFieldStyle.hover.textColor = new Color(0.1f, 0.14f, 0.2f, 1f); _textFieldStyle.focused.textColor = new Color(0.1f, 0.14f, 0.2f, 1f); _textFieldStyle.active.textColor = new Color(0.1f, 0.14f, 0.2f, 1f); _textFieldStyle.onNormal.textColor = new Color(0.1f, 0.14f, 0.2f, 1f); _textFieldStyle.onHover.textColor = new Color(0.1f, 0.14f, 0.2f, 1f); _textFieldStyle.onFocused.textColor = new Color(0.1f, 0.14f, 0.2f, 1f); _textFieldStyle.onActive.textColor = new Color(0.1f, 0.14f, 0.2f, 1f); _textFieldStyle.fontSize = 15; _textFieldStyle.alignment = (TextAnchor)4; _textFieldStyle.border = new RectOffset(0, 0, 0, 0); _textFieldStyle.padding = new RectOffset(6, 6, 4, 4); _textFieldHoverStyle = new GUIStyle(_textFieldStyle); Color textColor = default(Color); ((Color)(ref textColor))..ctor(0.07f, 0.26f, 0.64f, 1f); _textFieldHoverStyle.normal.background = _fieldTex; _textFieldHoverStyle.hover.background = _fieldTex; _textFieldHoverStyle.focused.background = _fieldTex; _textFieldHoverStyle.active.background = _fieldTex; _textFieldHoverStyle.onNormal.background = _fieldTex; _textFieldHoverStyle.onHover.background = _fieldTex; _textFieldHoverStyle.onFocused.background = _fieldTex; _textFieldHoverStyle.onActive.background = _fieldTex; _textFieldHoverStyle.normal.textColor = textColor; _textFieldHoverStyle.hover.textColor = textColor; _textFieldHoverStyle.focused.textColor = textColor; _textFieldHoverStyle.active.textColor = textColor; _textFieldHoverStyle.onNormal.textColor = textColor; _textFieldHoverStyle.onHover.textColor = textColor; _textFieldHoverStyle.onFocused.textColor = textColor; _textFieldHoverStyle.onActive.textColor = textColor; _switchOnStyle = new GUIStyle(GUI.skin.button); _switchOnStyle.normal.background = _switchOnTex; _switchOnStyle.hover.background = _switchOnHoverTex; _switchOnStyle.active.background = _switchOnHoverTex; _switchOnStyle.normal.textColor = Color.white; _switchOnStyle.hover.textColor = Color.white; _switchOnStyle.active.textColor = Color.white; _switchOnStyle.fontSize = 15; _switchOnStyle.fontStyle = (FontStyle)1; _switchOnStyle.alignment = (TextAnchor)4; _switchOnStyle.border = new RectOffset(0, 0, 0, 0); _switchOffStyle = new GUIStyle(GUI.skin.button); _switchOffStyle.normal.background = _switchOffTex; _switchOffStyle.hover.background = _switchOffHoverTex; _switchOffStyle.active.background = _switchOffHoverTex; _switchOffStyle.normal.textColor = Color.white; _switchOffStyle.hover.textColor = Color.white; _switchOffStyle.active.textColor = Color.white; _switchOffStyle.fontSize = 15; _switchOffStyle.fontStyle = (FontStyle)1; _switchOffStyle.alignment = (TextAnchor)4; _switchOffStyle.border = new RectOffset(0, 0, 0, 0); _closeStyle = new GUIStyle(GUI.skin.button); _closeStyle.normal.background = _btnTex; _closeStyle.hover.background = _btnHoverTex; _closeStyle.active.background = _btnHoverTex; _closeStyle.normal.textColor = Color.white; _closeStyle.hover.textColor = Color.white; _closeStyle.active.textColor = Color.white; _closeStyle.fontSize = 14; _closeStyle.fontStyle = (FontStyle)1; _closeStyle.alignment = (TextAnchor)4; _closeStyle.border = new RectOffset(0, 0, 0, 0); } } private static Texture2D MakeTexture(int width, int height, Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(width, height, (TextureFormat)5, false); ((Texture)val).wrapMode = (TextureWrapMode)1; Color[] array = (Color[])(object)new Color[width * height]; for (int i = 0; i < array.Length; i++) { array[i] = color; } val.SetPixels(array); val.Apply(); return val; } private static void SafeDestroy(ref Texture2D tex) { if ((Object)(object)tex != (Object)null) { Object.DestroyImmediate((Object)(object)tex); tex = null; } } } public static class ModConfig { public static ConfigEntry<bool> EnableChaosMaster { get; private set; } public static ConfigEntry<int> WaitTimeMin { get; private set; } public static ConfigEntry<int> WaitTimeMax { get; private set; } public static ConfigEntry<bool> EnableItemRandomization { get; private set; } public static ConfigEntry<bool> EnableRandomEvents { get; private set; } public static ConfigEntry<int> TropicsRain { get; private set; } public static ConfigEntry<int> RootsWindRandom { get; private set; } public static ConfigEntry<int> AlpineSnowRandom { get; private set; } public static ConfigEntry<int> MesaSunRandom { get; private set; } public static ConfigEntry<int> MesaSunDurationMin { get; private set; } public static ConfigEntry<int> MesaSunDurationMax { get; private set; } public static ConfigEntry<bool> ShowSettingsButton { get; private set; } public static ConfigEntry<float> SettingsButtonTopOffset { get; private set; } public static ConfigEntry<KeyCode> ToggleGuiKey { get; private set; } public static ConfigEntry<int> Tornado { get; private set; } public static ConfigEntry<int> Tick { get; private set; } public static ConfigEntry<int> Bees { get; private set; } public static ConfigEntry<int> Tumbleweed { get; private set; } public static ConfigEntry<int> Dynamite { get; private set; } public static ConfigEntry<int> Zombie { get; private set; } public static ConfigEntry<int> Mandrake { get; private set; } public static ConfigEntry<int> Cactus { get; private set; } public static ConfigEntry<int> RandomItem { get; private set; } public static ConfigEntry<int> RandomGoodItem { get; private set; } public static ConfigEntry<int> RandomGoodItemRain { get; private set; } public static ConfigEntry<int> BingBongRain { get; private set; } public static ConfigEntry<int> CureAll { get; private set; } public static ConfigEntry<int> Pandora { get; private set; } public static ConfigEntry<int> SwapPlayers { get; private set; } public static ConfigEntry<int> WarpToLastPlayer { get; private set; } public static ConfigEntry<int> SwapPlayerItems { get; private set; } public static ConfigEntry<int> SwapPlayerStatuses { get; private set; } public static ConfigEntry<int> ReviveOne { get; private set; } public static ConfigEntry<int> ReviveAll { get; private set; } public static ConfigEntry<int> HealShroom { get; private set; } public static ConfigEntry<int> BounceShroom { get; private set; } public static ConfigEntry<int> MoraleBoost { get; private set; } public static ConfigEntry<int> Scorpion { get; private set; } public static ConfigEntry<int> RandomBackpackGood { get; private set; } public static ConfigEntry<int> RandomBackpack { get; private set; } public static ConfigEntry<int> Beanstalk { get; private set; } public static ConfigEntry<int> BeanstalkSpam { get; private set; } public static ConfigEntry<int> EnergyDrink { get; private set; } public static ConfigEntry<int> Lollipop { get; private set; } public static ConfigEntry<int> Milk { get; private set; } public static ConfigEntry<int> UnlimitedPower { get; private set; } public static ConfigEntry<int> TwoAtOnce { get; private set; } public static ConfigEntry<int> Skeleton { get; private set; } public static ConfigEntry<int> TieBalloon { get; private set; } public static ConfigEntry<int> TieThreeBalloons { get; private set; } public static ConfigEntry<int> Web { get; private set; } public static ConfigEntry<int> Antirope { get; private set; } public static ConfigEntry<int> PitonPatch { get; private set; } public static ConfigEntry<int> ChainCache { get; private set; } public static ConfigEntry<int> ToxicBounceShroom { get; private set; } public static ConfigEntry<int> LowGravityShroom { get; private set; } public static ConfigEntry<int> SleepySpores { get; private set; } public static ConfigEntry<int> FungusCloud { get; private set; } public static ConfigEntry<int> DayNight { get; private set; } public static ConfigEntry<int> Eruption { get; private set; } public static ConfigEntry<bool> EnableTornadoAtKiln { get; private set; } public static ConfigEntry<float> ExtendedDynamiteChance { get; private set; } public static ConfigEntry<float> BoobyTrappedBackpacksChance { get; private set; } public static void Startup(ConfigFile config) { EnableChaosMaster = config.Bind<bool>("General", "EnableChaosMaster", true, "Master switch. OFF = disable random loot and random events."); EnableItemRandomization = config.Bind<bool>("General", "EnableItemRandomization", true, "Enable randomized item spawns."); EnableRandomEvents = config.Bind<bool>("General", "EnableRandomEvents", true, "Enable random events."); WaitTimeMin = config.Bind<int>("Events.Timer", "WaitTimeMin", 30, "Minimum seconds between random events."); WaitTimeMax = config.Bind<int>("Events.Timer", "WaitTimeMax", 60, "Maximum seconds between random events."); ShowSettingsButton = config.Bind<bool>("GUI", "ShowSettingsButton", true, "Show the in-game settings button."); SettingsButtonTopOffset = config.Bind<float>("GUI", "SettingsButtonTopOffset", 66f, "Top offset of the settings button."); ToggleGuiKey = config.Bind<KeyCode>("GUI", "ToggleGuiKey", (KeyCode)289, "Keyboard key to open/close the chaos settings window."); EnableTornadoAtKiln = config.Bind<bool>("Events.Settings", "EnableTornadoAtKiln", false, "Enable Tornado at Kiln."); ExtendedDynamiteChance = config.Bind<float>("Events.Settings", "ExtendedDynamiteChance", 0.1f, "Chance for extended dynamite."); BoobyTrappedBackpacksChance = config.Bind<float>("Events.Settings", "BoobyTrappedBackpacksChance", 0.1f, "Chance for troll backpack."); MesaSunDurationMin = config.Bind<int>("Events.Settings", "MesaSunDurationMin", 10, "Minimum duration in seconds for random global hot sun / sunburn event."); MesaSunDurationMax = config.Bind<int>("Events.Settings", "MesaSunDurationMax", 30, "Maximum duration in seconds for random global hot sun / sunburn event."); TropicsRain = config.Bind<int>("Events.Weights", "TropicsRain", 0, "Default 0 = disabled unless explicitly enabled."); RootsWindRandom = config.Bind<int>("Events.Weights", "RootsWindRandom", 0, "Default 0 = disabled unless explicitly enabled."); AlpineSnowRandom = config.Bind<int>("Events.Weights", "AlpineSnowRandom", 0, "Default 0 = disabled unless explicitly enabled."); MesaSunRandom = config.Bind<int>("Events.Weights", "MesaSunRandom", 0, "Default 0 = disabled unless explicitly enabled."); Tornado = config.Bind<int>("Events.Weights", "Tornado", 50, ""); Tick = config.Bind<int>("Events.Weights", "Tick", 70, ""); Bees = config.Bind<int>("Events.Weights", "Bees", 10, ""); Tumbleweed = config.Bind<int>("Events.Weights", "Tumbleweed", 100, ""); Dynamite = config.Bind<int>("Events.Weights", "Dynamite", 20, ""); Zombie = config.Bind<int>("Events.Weights", "Zombie", 60, ""); Mandrake = config.Bind<int>("Events.Weights", "Mandrake", 90, ""); Cactus = config.Bind<int>("Events.Weights", "Cactus", 100, ""); RandomItem = config.Bind<int>("Events.Weights", "RandomItem", 100, ""); RandomGoodItem = config.Bind<int>("Events.Weights", "RandomGoodItem", 20, ""); RandomGoodItemRain = config.Bind<int>("Events.Weights", "RandomGoodItemRain", 10, ""); BingBongRain = config.Bind<int>("Events.Weights", "BingBongRain", 15, ""); CureAll = config.Bind<int>("Events.Weights", "CureAll", 20, ""); Pandora = config.Bind<int>("Events.Weights", "Pandora", 50, ""); SwapPlayers = config.Bind<int>("Events.Weights", "SwapPlayers", 60, ""); WarpToLastPlayer = config.Bind<int>("Events.Weights", "WarpToLowestPlayer", 10, ""); SwapPlayerItems = config.Bind<int>("Events.Weights", "SwapPlayerItems", 50, ""); SwapPlayerStatuses = config.Bind<int>("Events.Weights", "SwapPlayerStatuses", 45, "Swap part or all of player statuses except backpack weight."); ReviveOne = config.Bind<int>("Events.Weights", "ReviveOne", 20, ""); ReviveAll = config.Bind<int>("Events.Weights", "ReviveAll", 10, ""); HealShroom = config.Bind<int>("Events.Weights", "HealShroom", 40, ""); BounceShroom = config.Bind<int>("Events.Weights", "BounceShroom", 80, ""); MoraleBoost = config.Bind<int>("Events.Weights", "MoraleBoost", 50, ""); Scorpion = config.Bind<int>("Events.Weights", "Scorpion", 60, ""); RandomBackpack = config.Bind<int>("Events.Weights", "RandomBackpack", 60, ""); RandomBackpackGood = config.Bind<int>("Events.Weights", "RandomBackpackGood", 10, ""); Beanstalk = config.Bind<int>("Events.Weights", "Beanstalk", 40, ""); BeanstalkSpam = config.Bind<int>("Events.Weights", "BeanstalkSpam", 10, ""); EnergyDrink = config.Bind<int>("Events.Weights", "EnergyDrink", 30, ""); Lollipop = config.Bind<int>("Events.Weights", "Lollipop", 30, ""); Milk = config.Bind<int>("Events.Weights", "Milk", 30, ""); UnlimitedPower = config.Bind<int>("Events.Weights", "UnlimitedPower", 10, ""); TwoAtOnce = config.Bind<int>("Events.Weights", "TwoAtOnce", 20, ""); Skeleton = config.Bind<int>("Events.Weights", "Skeleton", 10, ""); TieBalloon = config.Bind<int>("Events.Weights", "TieBalloon", 30, ""); TieThreeBalloons = config.Bind<int>("Events.Weights", "TieThreeBalloons", 10, ""); Web = config.Bind<int>("Events.Weights", "Web", 58, ""); Antirope = config.Bind<int>("Events.Weights", "Antirope", 20, ""); PitonPatch = config.Bind<int>("Events.Weights", "PitonPatch", 35, "Place 1-3 vanilla pitons on nearby walls, roughly 2-4m above random players. Host only chooses placement; spawned pitons are vanilla network objects."); ChainCache = config.Bind<int>("Events.Weights", "ChainCache", 22, "Place vanilla ChainShooter chains from near player feet toward a valid TerrainMap point 5-30m away; falls back to giving the item if no safe placement is found."); ToxicBounceShroom = config.Bind<int>("Events.Weights", "ToxicBounceShroom", 28, "Spawn small vanilla bounce-shroom traps and apply light poison/spores to selected players."); LowGravityShroom = config.Bind<int>("Events.Weights", "LowGravityShroom", 18, "Feed a vanilla mushroom whose current run effect is low gravity, when one can be found."); SleepySpores = config.Bind<int>("Events.Weights", "SleepySpores", 12, "Light drowsy/spore effect for a few random players. Lower weight and lower intensity because it is negative."); FungusCloud = config.Bind<int>("Events.Weights", "FungusCloud", 14, "Small vanilla spore-cloud burst around one player, affecting only nearby players."); DayNight = config.Bind<int>("Events.Weights", "DayNightSwap", 30, ""); Eruption = config.Bind<int>("Events.Weights", "Eruption", 70, ""); if (TropicsRain.Value == 35 && RootsWindRandom.Value == 35 && AlpineSnowRandom.Value == 25 && MesaSunRandom.Value == 30) { TropicsRain.Value = 0; RootsWindRandom.Value = 0; AlpineSnowRandom.Value = 0; MesaSunRandom.Value = 0; config.Save(); } } } public static class CustomLoot { public static readonly HashSet<string> ExcludedItemNames = new HashSet<string> { "Cheat Compass", "ScoutCookies_Vanilla", "ClimbingChalk", "Skull", "Warp Compass", "AncientIdol", "Passport" }; public static readonly HashSet<string> ExcludedItemPrefixes = new HashSet<string> { "C_", "Guidebook" }; public static readonly HashSet<string> ExcludedItemSuffixes = new HashSet<string> { "_Prop", "_Prop Variant", "_TEMP", "Spawn", "Placed" }; public static readonly HashSet<string> UnsafeForRandomLootNames = new HashSet<string> { "BingBong", "BugfixOnYou", "BeeSwarm", "TumbleWeed", "MushroomZombie", "RopeAnchorForRopeShooterAnti", "BounceShroomSpawn", "HealingPuffShroomSpawn", "ShelfShroomSpawn", "Anti-Rope Spool", "RopeShooterAnti", "RopeShooter", "VineShooter", "VineShooter Variant", "BananaPeel", "Banana Peel" }; public static readonly HashSet<string> UnsafeForRandomEventItemNames = new HashSet<string> { "Backpack", "BingBong", "BugfixOnYou", "BeeSwarm", "TumbleWeed", "MushroomZombie", "RopeAnchorForRopeShooterAnti", "BounceShroomSpawn", "HealingPuffShroomSpawn", "ShelfShroomSpawn", "Anti-Rope Spool", "RopeShooterAnti", "RopeShooter", "VineShooter", "VineShooter Variant", "BananaPeel", "Banana Peel" }; public static readonly HashSet<string> UnsafeForBushLootNames = new HashSet<string> { "Dynamite", "CactusBall", "Mandrake", "Scorpion", "MagicBean", "PandorasBox", "BingBong", "BugfixOnYou", "BeeSwarm", "TumbleWeed", "MushroomZombie", "RopeAnchorForRopeShooterAnti", "BounceShroomSpawn", "HealingPuffShroomSpawn", "ShelfShroomSpawn", "Backpack", "Anti-Rope Spool", "RopeShooterAnti", "BalloonBunch", "ChainShooter", "Flag_Plantable_Checkpoint" }; public static readonly HashSet<string> TrollItems = new HashSet<string> { "CactusBall", "Mandrake", "Dynamite", "Scorpion" }; public static readonly Dictionary<string, int> MaxSpawnCountByItemName = new Dictionary<string, int> { { "RescueHook_Infinite", 1 } }; private static readonly HashSet<string> GoodItemsBasic = new HashSet<string> { "Lantern_Faerie", "ChainShooter", "Cure-All", "FirstAidKit", "Glizzy", "Winterberry Yellow", "PandorasBox", "EggTurkey", "Napberry", "Flag_Plantable_Checkpoint" }; private static readonly HashSet<string> GoodItemsMultiplayer = new HashSet<string> { "Bugle_Magic", "ScoutEffigy", "HealingDart Variant" }; private static readonly HashSet<string> GoodItemsFloaty = new HashSet<string> { "BalloonBunch" }; private static readonly Dictionary<string, int> SpawnedCountByItemName = new Dictionary<string, int>(); private static readonly object CacheLock = new object(); private static Dictionary<ushort, Item>? _baseFilteredAllCache; private static Dictionary<ushort, Item>? _baseFilteredLootCache; private static Dictionary<ushort, Item>? _baseFilteredBushCache; private static Dictionary<ushort, Item>? _baseFilteredEventCache; private static Dictionary<ushort, Item>? _availableAllItemsCache; private static Dictionary<ushort, Item>? _availableLootItemsCache; private static Dictionary<ushort, Item>? _availableBushItemsCache; private static Dictionary<ushort, Item>? _availableEventItemsCache; private static bool _availableCachesDirty = true; public static readonly HashSet<string> UnsafeForHangingLootNames = new HashSet<string> { "Dynamite", "CactusBall", "Mandrake", "Scorpion", "MagicBean", "PandorasBox", "BingBong", "BugfixOnYou", "BeeSwarm", "TumbleWeed", "MushroomZombie", "RopeAnchorForRopeShooterAnti", "BounceShroomSpawn", "HealingPuffShroomSpawn", "ShelfShroomSpawn", "BalloonBunch", "Anti-Rope Spool", "RopeShooterAnti", "ChainShooter", "Flag_Plantable_Checkpoint", "Backpack" }; public static HashSet<string> GoodItems { get { IEnumerable<string> enumerable = new HashSet<string>().Concat(GoodItemsBasic); if (Character.AllCharacters.Count((Character c) => (Object)(object)c != (Object)null && !c.isBot) > 1) { enumerable = enumerable.Concat(GoodItemsMultiplayer); } return enumerable.ToHashSet(); } } public static HashSet<string> GoodItemsBackpack { get { IEnumerable<string> first = new HashSet<string>().Concat(GoodItemsBasic); if (Character.AllCharacters.Count((Character c) => (Object)(object)c != (Object)null && !c.isBot) > 1) { first = first.Concat(GoodItemsMultiplayer); } first = first.Concat(GoodItemsFloaty); return first.ToHashSet(); } } public static void ResetRuntimeState() { lock (CacheLock) { SpawnedCountByItemName.Clear(); _baseFilteredAllCache = null; _baseFilteredLootCache = null; _baseFilteredBushCache = null; _baseFilteredEventCache = null; _availableAllItemsCache = null; _availableLootItemsCache = null; _availableBushItemsCache = null; _availableEventItemsCache = null; _availableCachesDirty = true; } } public static void NotifyFiltersChanged() { lock (CacheLock) { _availableAllItemsCache = null; _availableLootItemsCache = null; _availableBushItemsCache = null; _availableEventItemsCache = null; _availableCachesDirty = true; } } private static bool IsHardExcluded(string itemName) { string itemName2 = itemName; if (ExcludedItemNames.Contains(itemName2)) { return true; } if (ExcludedItemPrefixes.Any((string prefix) => itemName2.StartsWith(prefix))) { return true; } if (ExcludedItemSuffixes.Any((string suffix) => itemName2.EndsWith(suffix))) { return true; } if (MaxSpawnCountByItemName.TryGetValue(itemName2, out var value) && value <= 0) { return true; } return false; } private static bool IsBlockedBySpawnLimit(string itemName) { if (!MaxSpawnCountByItemName.TryGetValue(itemName, out var value)) { return false; } int value2; int num = (SpawnedCountByItemName.TryGetValue(itemName, out value2) ? value2 : 0); return num >= value; } public static void MarkSpawned(string itemName) { if (MaxSpawnCountByItemName.ContainsKey(itemName)) { if (!SpawnedCountByItemName.ContainsKey(itemName)) { SpawnedCountByItemName[itemName] = 0; } SpawnedCountByItemName[itemName]++; _availableCachesDirty = true; } } public static Dictionary<ushort, Item> GetHangingItemsDatabaseFiltered() { ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance; return instance.itemLookup.Where((KeyValuePair<ushort, Item> pair) => (Object)(object)pair.Value != (Object)null && !IsHardExcluded(((Object)pair.Value).name) && !UnsafeForRandomLootNames.Contains(((Object)pair.Value).name) && !UnsafeForHangingLootNames.Contains(((Object)pair.Value).name) && pair.Value.IsValidToSpawn() && pair.Value.UIData != null && pair.Value.UIData.canPocket && pair.Value.UIData.canDrop).ToDictionary((KeyValuePair<ushort, Item> pair) => pair.Key, (KeyValuePair<ushort, Item> pair) => pair.Value); } public static bool TryGetRandomHangingLootItem(out Item item) { item = null; Dictionary<ushort, Item> hangingItemsDatabaseFiltered = GetHangingItemsDatabaseFiltered(); if (hangingItemsDatabaseFiltered.Count == 0) { return false; } item = hangingItemsDatabaseFiltered.ElementAt(Random.Range(0, hangingItemsDatabaseFiltered.Count)).Value; return (Object)(object)item != (Object)null; } private static bool IsSafeInventoryItem(Item item) { if ((Object)(object)item == (Object)null) { return false; } if (!item.IsValidToSpawn()) { return false; } if (item.UIData == null) { return false; } if (!item.UIData.canPocket) { return false; } if (!item.UIData.canDrop) { return false; } return true; } private static bool IsSafeRandomEventItem(Item item) { if ((Object)(object)item == (Object)null) { return false; } if (!item.IsValidToSpawn()) { return false; } if (item.UIData == null) { return false; } if (!item.UIData.canDrop) { return false; } if (UnsafeForRandomLootNames.Contains(((Object)item).name) || UnsafeForRandomEventItemNames.Contains(((Object)item).name)) { return false; } return true; } private static bool IsSafeBushItem(Item item) { if (!IsSafeInventoryItem(item)) { return false; } return !UnsafeForBushLootNames.Contains(((Object)item).name); } private static Dictionary<ushort, Item> BuildBaseFiltered(bool lootOnly, bool bushOnly, bool eventOnly = false) { ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance; return instance.itemLookup.Where((KeyValuePair<ushort, Item> pair) => (Object)(object)pair.Value != (Object)null && (eventOnly ? IsSafeRandomEventItem(pair.Value) : IsSafeInventoryItem(pair.Value)) && !IsHardExcluded(((Object)pair.Value).name) && (!lootOnly || !UnsafeForRandomLootNames.Contains(((Object)pair.Value).name)) && (!bushOnly || IsSafeBushItem(pair.Value))).ToDictionary((KeyValuePair<ushort, Item> pair) => pair.Key, (KeyValuePair<ushort, Item> pair) => pair.Value); } private static Dictionary<ushort, Item> BuildAvailableFromBase(Dictionary<ushort, Item> baseCache) { return baseCache.Where<KeyValuePair<ushort, Item>>((KeyValuePair<ushort, Item> pair) => !IsBlockedBySpawnLimit(((Object)pair.Value).name)).ToDictionary((KeyValuePair<ushort, Item> pair) => pair.Key, (KeyValuePair<ushort, Item> pair) => pair.Value); } private static void EnsureAvailableCaches() { lock (CacheLock) { if (_baseFilteredAllCache == null) { _baseFilteredAllCache = BuildBaseFiltered(lootOnly: false, bushOnly: false); } if (_baseFilteredLootCache == null) { _baseFilteredLootCache = BuildBaseFiltered(lootOnly: true, bushOnly: false); } if (_baseFilteredBushCache == null) { _baseFilteredBushCache = BuildBaseFiltered(lootOnly: true, bushOnly: true); } if (_baseFilteredEventCache == null) { _baseFilteredEventCache = BuildBaseFiltered(lootOnly: false, bushOnly: false, eventOnly: true); } if (_availableCachesDirty || _availableAllItemsCache == null || _availableLootItemsCache == null || _availableBushItemsCache == null || _availableEventItemsCache == null) { _availableAllItemsCache = BuildAvailableFromBase(_baseFilteredAllCache); _availableLootItemsCache = BuildAvailableFromBase(_baseFilteredLootCache); _availableBushItemsCache = BuildAvailableFromBase(_baseFilteredBushCache); _availableEventItemsCache = BuildAvailableFromBase(_baseFilteredEventCache); _availableCachesDirty = false; } } } public static ushort GetRandomId() { EnsureAvailableCaches(); Dictionary<ushort, Item> availableEventItemsCache = _availableEventItemsCache; if (availableEventItemsCache.Count == 0) { return 0; } Dictionary<ushort, Item>.KeyCollection keys = availableEventItemsCache.Keys; return keys.ElementAt(Random.Range(0, keys.Count)); } public static Dictionary<ushort, Item> GetItemsDatabaseFiltered() { EnsureAvailableCaches(); return _availableAllItemsCache; } public static Dictionary<ushort, Item> GetEventItemsDatabaseFiltered() { EnsureAvailableCaches(); return _availableEventItemsCache; } public static Dictionary<ushort, Item> GetLootItemsDatabaseFiltered() { EnsureAvailableCaches(); return _availableLootItemsCache; } public static Dictionary<ushort, Item> GetBushItemsDatabaseFiltered() { EnsureAvailableCaches(); return _availableBushItemsCache; } public static bool TryGetRandomItem(out Item item) { item = null; Dictionary<ushort, Item> itemsDatabaseFiltered = GetItemsDatabaseFiltered(); if (itemsDatabaseFiltered.Count == 0) { return false; } item = itemsDatabaseFiltered.ElementAt(Random.Range(0, itemsDatabaseFiltered.Count)).Value; return (Object)(object)item != (Object)null; } public static bool TryGetRandomEventItem(out Item item) { item = null; Dictionary<ushort, Item> eventItemsDatabaseFiltered = GetEventItemsDatabaseFiltered(); if (eventItemsDatabaseFiltered.Count == 0) { return false; } item = eventItemsDatabaseFiltered.ElementAt(Random.Range(0, eventItemsDatabaseFiltered.Count)).Value; return (Object)(object)item != (Object)null; } public static bool TryGetRandomLootItem(out Item item) { item = null; Dictionary<ushort, Item> lootItemsDatabaseFiltered = GetLootItemsDatabaseFiltered(); if (lootItemsDatabaseFiltered.Count == 0) { return false; } item = lootItemsDatabaseFiltered.ElementAt(Random.Range(0, lootItemsDatabaseFiltered.Count)).Value; return (Object)(object)item != (Object)null; } public static bool TryGetRandomBushLootItem(out Item item) { item = null; Dictionary<ushort, Item> bushItemsDatabaseFiltered = GetBushItemsDatabaseFiltered(); if (bushItemsDatabaseFiltered.Count == 0) { return false; } item = bushItemsDatabaseFiltered.ElementAt(Random.Range(0, bushItemsDatabaseFiltered.Count)).Value; return (Object)(object)item != (Object)null; } } public static class LootTablePatch { [ThreadStatic] private static int _suppressGenericLootRandomizationDepth; private static readonly int TerrainMask = LayerMask.GetMask(new string[2] { "Terrain", "Map" }); private static bool IsGenericLootRandomizationSuppressed() { return _suppressGenericLootRandomizationDepth > 0; } private static void PushGenericLootRandomizationSuppression() { _suppressGenericLootRandomizationDepth++; } private static void PopGenericLootRandomizationSuppression() { if (_suppressGenericLootRandomizationDepth > 0) { _suppressGenericLootRandomizationDepth--; } } [HarmonyPatch(typeof(LootData), "GetRandomItem")] [HarmonyPrefix] private static bool PrefixGetRandomItem(SpawnPool spawnPool, ref GameObject __result) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected I4, but got Unknown if (!Plugin.IsGameplayScene()) { return true; } if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableItemRandomization.Value) { return true; } if (IsGenericLootRandomizationSuppressed()) { return true; } int num = (int)spawnPool; if (num == 131072 || num == 32768 || num == 65536) { return true; } if (LootData.AllSpawnWeightData == null) { LootData.PopulateLootData(); } if (CustomLoot.TryGetRandomLootItem(out Item item)) { CustomLoot.MarkSpawned(((Object)item).name); __result = ((Component)item).gameObject; return false; } return true; } [HarmonyPatch(typeof(LootData), "GetRandomItems")] [HarmonyPrefix] private static bool PrefixGetRandomItems(SpawnPool spawnPool, int count, bool canRepeat, ref List<GameObject> __result) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected I4, but got Unknown if (!Plugin.IsGameplayScene()) { return true; } if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableItemRandomization.Value) { return true; } if (IsGenericLootRandomizationSuppressed()) { return true; } int num = (int)spawnPool; if (num == 131072 || num == 32768 || num == 65536) { return true; } if (LootData.AllSpawnWeightData == null) { LootData.PopulateLootData(); } __result = new List<GameObject>(count); for (int i = 0; i < count; i++) { if (CustomLoot.TryGetRandomLootItem(out Item item)) { CustomLoot.MarkSpawned(((Object)item).name); __result.Add(((Component)item).gameObject); } } return __result.Count <= 0; } [HarmonyPatch(typeof(SpawnList), "GetSpawns")] [HarmonyPrefix] private static bool PrefixSpawnListGetSpawns(int count, bool canRepeat, ref List<GameObject> __result) { if (!Plugin.IsGameplayScene()) { return true; } if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableItemRandomization.Value) { return true; } if (IsGenericLootRandomizationSuppressed()) { return true; } __result = new List<GameObject>(count); for (int i = 0; i < count; i++) { if (CustomLoot.TryGetRandomLootItem(out Item item)) { CustomLoot.MarkSpawned(((Object)item).name); __result.Add(((Component)item).gameObject); } } return __result.Count <= 0; } [HarmonyPatch(typeof(SpawnList), "GetSingleSpawn")] [HarmonyPrefix] private static bool PrefixSpawnListGetSingleSpawn(ref GameObject __result) { if (!Plugin.IsGameplayScene()) { return true; } if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableItemRandomization.Value) { return true; } if (IsGenericLootRandomizationSuppressed()) { return true; } if (CustomLoot.TryGetRandomLootItem(out Item item)) { CustomLoot.MarkSpawned(((Object)item).name); __result = ((Component)item).gameObject; return false; } return true; } [HarmonyPatch(typeof(BerryBush), "SpawnItems")] [HarmonyPrefix] private static bool PrefixBerryBushSpawnItems(BerryBush __instance, List<Transform> spawnSpots, ref List<PhotonView> __result) { //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Invalid comparison between Unknown and I4 //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: 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_0353: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) List<PhotonView> list = (__result = new List<PhotonView>()); if (!Plugin.IsGameplayScene()) { return true; } if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableItemRandomization.Value) { return true; } if (!PhotonNetwork.IsMasterClient) { return false; } if ((Object)(object)__instance == (Object)null || spawnSpots == null || spawnSpots.Count == 0) { return false; } List<Transform> list2 = spawnSpots.Where((Transform s) => (Object)(object)s != (Object)null).ToList(); if (list2.Count == 0) { return false; } float num = Mathf.Pow(Random.value, __instance.randomPow); int num2 = Mathf.RoundToInt(Mathf.Lerp(__instance.possibleBerries.x, __instance.possibleBerries.y, num)); num2 = Mathf.Clamp(num2, 0, list2.Count); for (int i = 0; i < num2 && list2.Count != 0; i++) { int index = Random.Range(0, list2.Count); Transform val = list2[index]; list2.RemoveAt(index); if ((Object)(object)val == (Object)null) { continue; } GameObject val2 = null; Item item; if ((int)((Spawner)__instance).spawnMode == 0) { val2 = ((Spawner)__instance).spawnedObjectPrefab; } else if (CustomLoot.TryGetRandomBushLootItem(out item) && (Object)(object)item != (Object)null) { CustomLoot.MarkSpawned(((Object)item).name); val2 = ((Component)item).gameObject; } if ((Object)(object)val2 == (Object)null || string.IsNullOrEmpty(((Object)val2).name)) { continue; } GameObject val3; try { val3 = PhotonNetwork.InstantiateItemRoom(((Object)val2).name, val.position, Quaternion.identity); } catch (Exception arg) { Plugin.Log.LogWarning((object)$"BerryBush spawn failed: {((Object)val2).name}, {arg}"); continue; } if ((Object)(object)val3 == (Object)null) { continue; } Item component = val3.GetComponent<Item>(); PhotonView component2 = val3.GetComponent<PhotonView>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { Plugin.Log.LogWarning((object)("BerryBush spawned invalid object: " + ((Object)val2).name)); try { PhotonNetwork.Destroy(val3); } catch { } continue; } list.Add(component2); if (Object.op_Implicit((Object)(object)((Spawner)__instance).spawnUpTowardsTarget) && (Object)(object)((Spawner)__instance).spawnUpTowardsTarget != (Object)null) { Vector3 val4 = ((Spawner)__instance).spawnUpTowardsTarget.position - ((Component)component).transform.position; if (((Vector3)(ref val4)).sqrMagnitude > 0.0001f) { ((Component)component).transform.up = ((Vector3)(ref val4)).normalized; ((Component)component).transform.Rotate(Vector3.up, Random.Range(0f, 360f), (Space)1); } } if (((Spawner)__instance).spawnTransformIsSpawnerTransform) { ((Component)component).transform.rotation = val.rotation; ((Component)component).transform.Rotate(Vector3.up, Random.Range(0f, 360f), (Space)1); } try { component2.RPC("SetKinematicRPC", (RpcTarget)3, new object[3] { true, ((Component)component).transform.position, ((Component)component).transform.rotation }); } catch (Exception arg2) { Plugin.Log.LogWarning((object)$"BerryBush SetKinematicRPC failed: {arg2}"); } } __result = list; return false; } [HarmonyPatch(typeof(Spawner), "SpawnItems")] [HarmonyPrefix] private static void PrefixSpawnerSpawnItems(List<Transform> spawnSpots) { if (Plugin.IsGameplayScene() && ModConfig.EnableChaosMaster.Value && ModConfig.EnableItemRandomization.Value && spawnSpots != null && spawnSpots.Count != 0 && HasAnyHangingSpot(spawnSpots)) { PushGenericLootRandomizationSuppression(); } } [HarmonyPatch(typeof(Spawner), "SpawnItems")] [HarmonyFinalizer] private static Exception? FinalizerSpawnerSpawnItems(List<Transform> spawnSpots, Exception? __exception) { if (Plugin.IsGameplayScene() && ModConfig.EnableChaosMaster.Value && ModConfig.EnableItemRandomization.Value && spawnSpots != null && spawnSpots.Count > 0 && HasAnyHangingSpot(spawnSpots)) { PopGenericLootRandomizationSuppression(); } return __exception; } private static string GetTransformPath(Transform t) { if ((Object)(object)t == (Object)null) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(128); Transform val = t; while ((Object)(object)val != (Object)null) { if (stringBuilder.Length > 0) { stringBuilder.Insert(0, "/"); } stringBuilder.Insert(0, ((Object)val).name); val = val.parent; } return stringBuilder.ToString(); } private static bool IsHangingSpawnSpot(Transform spot) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)spot == (Object)null) { return false; } string text = GetTransformPath(spot).ToLowerInvariant(); if (text.Contains("vine") || text.Contains("junglevine") || text.Contains("tree") || text.Contains("branch") || text.Contains("root") || text.Contains("mushroom") || text.Contains("shroom") || text.Contains("hang")) { return true; } Vector3 val = spot.position + Vector3.up * 0.15f; RaycastHit val2 = default(RaycastHit); if (!Physics.Raycast(val, Vector3.down, ref val2, 1.35f, TerrainMask, (QueryTriggerInteraction)1)) { return true; } if (Vector3.Angle(((RaycastHit)(ref val2)).normal, Vector3.up) > 42f) { return true; } return false; } private static bool HasAnyHangingSpot(List<Transform> spawnSpots) { if (spawnSpots == null || spawnSpots.Count == 0) { return false; } for (int i = 0; i < spawnSpots.Count; i++) { if (IsHangingSpawnSpot(spawnSpots[i])) { return true; } } return false; } } public static class AchievementManagerPatch { [HarmonyPatch(typeof(AchievementManager), "ThrowAchievement")] [HarmonyPrefix] private static bool Prefix(AchievementManager __instance) { return false; } } public static class LoadingScreenHandlerPatch { [HarmonyPatch(typeof(LoadingScreenHandler), "LoadSceneProcess")] [HarmonyPrefix] public static bool Prefix(LoadingScreenHandler __instance, string sceneName, bool networked, bool yieldForCharacterSpawn, float extraYieldTimeOnEnd, ref IEnumerator __result) { switch ((sceneName ?? string.Empty).ToLowerInvariant()) { case "airport": case "mainmenu": case "title": case "pretitle": case "wilisland": ChaosEnvironmentController.ResetLocalState(); if (PhotonNetwork.IsMasterClient) { RandomEventTask.StopTask(); CustomLoot.ResetRuntimeState(); } break; } return true; } } public static class PauseMenuMainPagePatch { [HarmonyPatch(typeof(PauseMenuMainPage), "OnQuitClicked")] [HarmonyPrefix] public static bool Prefix(PauseMenuMainPage __instance) { ChaosEnvironmentController.ResetLocalState(); if (PhotonNetwork.IsMasterClient) { RandomEventTask.StopTask(); CustomLoot.ResetRuntimeState(); } return true; } } public static class MountainProgressHandlerPatch { [HarmonyPatch(typeof(MountainProgressHandler), "TriggerReached")] [HarmonyPrefix] public static bool Prefix(MountainProgressHandler __instance, ProgressPoint progressPoint) { ChaosEnvironmentController.ResetLocalState(); if (PhotonNetwork.IsMasterClient) { if (Singleton<MapHandler>.Instance.currentSegment == 0) { CustomLoot.ResetRuntimeState(); RandomizerEvents.ClearPendingQueues(); RandomEventTask.StartTask(); } else { RandomizerEvents.ClearPendingQueues(); QueueGarbageForCleanup(); } } return true; } private static void CollectGarbageOf<T>(List<GameObject> results) where T : MonoBehaviour { //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) if (results == null) { return; } MapHandler instance = Singleton<MapHandler>.Instance; if ((Object)(object)instance == (Object)null || instance.currentSegment <= 0 || instance.segments == null) { return; } int num = instance.currentSegment - 1; if (num < 0 || num >= instance.segments.Length) { return; } GameObject segmentCampfire = instance.segments[num].segmentCampfire; if ((Object)(object)segmentCampfire == (Object)null) { return; } T[] array = Object.FindObjectsByType<T>((FindObjectsInactive)1, (FindObjectsSortMode)0); T[] array2 = array; foreach (T val in array2) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)(object)val).gameObject == (Object)null) && segmentCampfire.transform.position.z - ((Component)(object)val).transform.position.z > 20f) { results.Add(((Component)(object)val).gameObject); } } } public static void QueueGarbageForCleanup() { List<GameObject> list = new List<GameObject>(); CollectGarbageOf<Item>(list); CollectGarbageOf<Luggage>(list); CollectGarbageOf<RopeAnchorProjectile>(list); CollectGarbageOf<RopeAnchorWithRope>(list); CollectGarbageOf<Rope>(list); CollectGarbageOf<JungleVine>(list); CollectGarbageOf<CheckpointFlag>(list); CollectGarbageOf<ClimbingSpikeComponent>(list); CollectGarbageOf<ShittyPiton>(list); CollectGarbageOf<ScoutCannon>(list); if (list.Count == 0) { return; } foreach (GameObject item in list.Distinct()) { RandomizerEvents.RemoveObjectAfterTime(item, 0f); } } } public static class GameHandlerPatch { private const int MaxEventsPerFrame = 1; private const int MaxDestroyPerFrame = 24; [HarmonyPatch(typeof(GameHandler), "Update")] [HarmonyPrefix] private static bool Prefix(GameHandler __instance) { if (!PhotonNetwork.IsMasterClient) { return true; } if (!Plugin.IsGameplayScene()) { return true; } if (ModConfig.EnableChaosMaster.Value && ModConfig.EnableRandomEvents.Value) { RandomEventTask.EnsureStarted(); } RandomizerEvents.FlushScheduledWork(); List<string> list = RandomizerEvents.DequeueEvents(1); foreach (string name in list) { try { (string, ConfigEntry<int>, Action) tuple = RandomizerEvents.Events.FirstOrDefault<(string, ConfigEntry<int>, Action)>(((string name, ConfigEntry<int> weightConfigEntry, Action action) e) => e.name == name); if (tuple.Item3 == null) { Plugin.Log.LogWarning((object)("Unknown or empty random event: " + name)); continue; } tuple.Item3(); RandomizerEvents.CleanupOrphanTemporarySlotsForAll("after " + name); } catch (Exception arg) { Plugin.Log.LogError((object)$"Error when trying to execute {name}: {arg}"); } } List<GameObject> list2 = RandomizerEvents.DequeueDestroy(24); foreach (GameObject item in list2) { try { if (!((Object)(object)item == (Object)null)) { PhotonView component = item.GetComponent<PhotonView>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)item); } else { PhotonNetwork.Destroy(item); } } } catch (Exception arg2) { Plugin.Log.LogWarning((object)$"Destroy queue error: {arg2}"); } } return true; } } public static class TornadoCompatibilityPatch { [HarmonyPatch] private static class TornadoFixedUpdatePatch { private static bool Prepare() { Type type = AccessTools.TypeByName("Tornado"); return type != null && AccessTools.Method(type, "FixedUpdate", (Type[])null, (Type[])null) != null; } private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("Tornado"), "FixedUpdate", (Type[])null, (Type[])null); } private static bool Prefix(object __instance) { if (!NeedsFallbackFixedUpdate()) { return true; } RunFallbackTornadoFixedUpdate(__instance); return false; } private static Exception? Finalizer(object __instance, Exception? __exception) { if (IsRemovedFallRpcException(__exception)) { RunFallbackTornadoFixedUpdate(__instance); return null; } return __exception; } } [HarmonyPatch] private static class TornadoCapturedCharacterPatch { private static bool Prepare() { Type type = AccessTools.TypeByName("Tornado"); return type != null && AccessTools.Method(type, "CapturedCharacter", (Type[])null, (Type[])null) != null; } private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("Tornado"), "CapturedCharacter", (Type[])null, (Type[])null); } private static Exception? Finalizer(object __instance, Exception? __exception) { if (IsRemovedFallRpcException(__exception)) { RunFallbackTornadoFixedUpdate(__instance); return null; } return __exception; } } private const float FallbackMoveSpeed = 18f; private const float FallbackAffectRadius = 24f; private const float FallbackFallRadius = 9f; private const float FallbackPullImpulse = 26f; private const float FallbackLiftImpulse = 34f; private const float FallbackSpinImpulse = 22f; private const float FallbackFallSeconds = 0.85f; private const float FallbackFallCooldown = 0.9f; private static readonly Dictionary<int, float> NextFallTimeByViewId = new Dictionary<int, float>(); private static int _warnedFallbackMode; private static int _warnedMissingTarget; private static MethodInfo? _characterFallMethod; private static MethodInfo? _characterAddForceAtPositionMethod; private static MethodInfo? CharacterFallMethod { get { if ((object)_characterFallMethod == null) { _characterFallMethod = AccessTools.Method(typeof(Character), "Fall", new Type[2] { typeof(float), typeof(float) }, (Type[])null); } return _characterFallMethod; } } private static MethodInfo? CharacterAddForceAtPositionMethod { get { if ((object)_characterAddForceAtPositionMethod == null) { _characterAddForceAtPositionMethod = AccessTools.Method(typeof(Character), "AddForceAtPosition", new Type[3] { typeof(Vector3), typeof(Vector3), typeof(float) }, (Type[])null); } return _characterAddForceAtPositionMethod; } } public static bool CanUseTornadoEvent() { return true; } private static bool HasLegacyFallRpcOverload() { return AccessTools.Method(typeof(Character), "RPCA_Fall", new Type[2] { typeof(float), typeof(PhotonMessageInfo) }, (Type[])null) != null; } private static bool NeedsFallbackFixedUpdate() { return !HasLegacyFallRpcOverload(); } private static bool IsRemovedFallRpcException(Exception? exception) { if (exception == null) { return false; } if (exception is MissingMethodException && exception.Message.IndexOf("Character.RPCA_Fall", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } return exception.InnerException != null && IsRemovedFallRpcException(exception.InnerException); } private static void LogFallbackOnce(string reason) { if (Interlocked.Exchange(ref _warnedFallbackMode, 1) == 0) { Plugin.Log.LogWarning((object)("Tornado compatibility mode active: " + reason + ". The Tornado event is still enabled; only the removed RPCA_Fall overload is replaced with the current Character.Fall/RPCA_Fall(float) path.")); } } private static Transform? TryGetTargetTransform(object tornado) { Type type = tornado.GetType(); try { FieldInfo fieldInfo = AccessTools.Field(type, "target"); if (fieldInfo != null) { object? value = fieldInfo.GetValue(tornado); Transform val = (Transform)((value is Transform) ? value : null); if (val != null) { return val; } } PropertyInfo propertyInfo = AccessTools.Property(type, "target"); if (propertyInfo != null) { object? value2 = propertyInfo.GetValue(tornado, null); Transform val2 = (Transform)((value2 is Transform) ? value2 : null); if (val2 != null) { return val2; } } } catch (Exception arg) { if (Interlocked.Exchange(ref _warnedMissingTarget, 1) == 0) { Plugin.Log.LogWarning((object)$"Tornado compatibility could not read target transform: {arg}"); } } return null; } private static bool IsFallbackCharacterUsable(Character character) { if ((Object)(object)character == (Object)null || (Object)(object)((MonoBehaviourPun)character).photonView == (Object)null || (Object)(object)character.view == (Object)null || (Object)(object)character.data == (Object)null || character.refs == null || (Object)(object)character.refs.items == (Object)null) { return false; } if (!character.IsPlayerControlled || character.isBot || character.isZombie || character.isScoutmaster) { return false; } if (!character.IsRegisteredToPlayer) { return false; } Player player = character.player; if ((Object)(object)player == (Object)null || (Object)(object)((MonoBehaviourPun)player).photonView == (Object)null || (Object)(object)player.view == (Object)null || (Object)(object)player.character != (Object)(object)character) { return false; } if (character.data.dead || character.data.fullyPassedOut || character.data.isInFog) { return false; } return true; } private static bool TryGetCharacterCenter(Character character, out Vector3 center) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) center = Vector3.zero; try { center = character.Center; return true; } catch { if ((Object)(object)character != (Object)null && (Object)(object)((Component)character).transform != (Object)null) { center = ((Component)character).transform.position; return true; } } return false; } private static void ApplyTornadoForce(Character character, Vector3 tornadoPosition, Vector3 characterCenter, float strength) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0044: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) Vector3 val = tornadoPosition - characterCenter; val.y = 0f; Vector3 val2 = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val)).normalized : Vector3.zero); Vector3 val4; if (!(val2 == Vector3.zero)) { Vector3 val3 = Vector3.Cross(Vector3.up, val2); val4 = ((Vector3)(ref val3)).normalized; } else { val4 = Vector3.zero; } Vector3 val5 = val4; Vector3 val6 = val2 * (26f * strength) + Vector3.up * (34f * strength) + val5 * (22f * strength); MethodInfo characterAddForceAtPositionMethod = CharacterAddForceAtPositionMethod; if (characterAddForceAtPositionMethod != null) { try { characterAddForceAtPositionMethod.Invoke(character, new object[3] { val6 * Mathf.Max(Time.fixedDeltaTime, 0.015f), characterCenter, 24f }); return; } catch (Exception arg) { Plugin.Log.LogWarning((object)$"Tornado compatibility AddForceAtPosition failed for {((Object)character).name}: {arg}"); } } try { character.RPCA_AddForceAtPosition(val6 * Mathf.Max(Time.fixedDeltaTime, 0.015f), characterCenter, 24f); } catch (Exception arg2) { Plugin.Log.LogWarning((object)$"Tornado compatibility local RPCA_AddForceAtPosition fallback failed for {((Object)character).name}: {arg2}"); } } private static void FallCharacterCompat(Character character, float seconds) { int key = (((Object)(object)((MonoBehaviourPun)character).photonView != (Object)null) ? ((MonoBehaviourPun)character).photonView.ViewID : ((Object)character).GetInstanceID()); float time = Time.time; if (NextFallTimeByViewId.TryGetValue(key, out var value) && time < value) { return; } NextFallTimeByViewId[key] = time + 0.9f; MethodInfo characterFallMethod = CharacterFallMethod; if (characterFallMethod != null) { try { characterFallMethod.Invoke(character, new object[2] { seconds, 0f }); return; } catch (Exception arg) { Plugin.Log.LogWarning((object)$"Tornado compatibility Character.Fall failed for {((Object)character).name}: {arg}"); } } try { character.refs.view.RPC("RPCA_Fall", (RpcTarget)0, new object[1] { seconds }); } catch (Exception arg2) { Plugin.Log.LogWarning((object)$"Tornado compatibility RPCA_Fall(float) fallback failed for {((Object)character).name}: {arg2}"); } } private static void RunFallbackTornadoFixedUpdate(object tornadoInstance) { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_0069: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_013b: 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_0173: 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) Component val = (Component)((tornadoInstance is Component) ? tornadoInstance : null); if (val == null || (Object)(object)val == (Object)null) { return; } LogFallbackOnce("Character.RPCA_Fall(float, PhotonMessageInfo) is not present in this game build"); Transform transform = val.transform; Transform val2 = TryGetTargetTransform(tornadoInstance); float num = Mathf.Max(Time.fixedDeltaTime, 0.015f); if ((Object)(object)val2 != (Object)null) { Vector3 val3 = transform.position; Vector3 position = val2.position; Vector3 val4 = position - val3; val4.y = 0f; if (((Vector3)(ref val4)).sqrMagnitude > 0.01f) { val3 += ((Vector3)(ref val4)).normalized * 18f * num; } val3.y = Mathf.Lerp(val3.y, position.y, Mathf.Clamp01(num * 2f)); transform.position = val3; } transform.Rotate(Vector3.up, 420f * num, (Space)0); Character[] array = Character.AllCharacters.ToArray(); foreach (Character character in array) { if (!IsFallbackCharacterUsable(character) || !TryGetCharacterCenter(character, out var center)) { continue; } float num2 = Vector3.Distance(transform.position, center); if (!(num2 > 24f)) { float strength = Mathf.Clamp01(1f - num2 / 24f); ApplyTornadoForce(character, transform.position, center, strength); if (num2 <= 9f) { FallCharacterCompat(character, 0.85f); } } } } } public static class ItemOptimizationCompatibilityPatch { [HarmonyPatch] private static class DeregisterItemPatch { private static bool Prepare() { Type type = AccessTools.TypeByName("Peak.ItemOptimizationManager"); return type != null && AccessTools.Method(type, "DeregisterItem", (Type[])null, (Type[])null) != null; } private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("Peak.ItemOptimizationManager"), "DeregisterItem", (Type[])null, (Type[])null); } private static Exception? Finalizer(Exception? __exception) { return SwallowNullKeyDeregister(__exception, "DeregisterItem"); } } [HarmonyPatch] private static class ItemOptimizerOnDisablePatch { private static bool Prepare() { Type type = AccessTools.TypeByName("Peak.ItemOptimizer"); return type != null && AccessTools.Method(type, "OnDisable", (Type[])null, (Type[])null) != null; } private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("Peak.ItemOptimizer"), "OnDisable", (Type[])null, (Type[])null); } private static Exception? Finalizer(Exception? __exception) { return SwallowNullKeyDeregister(__exception, "ItemOptimizer.OnDisable"); } } private static int _warned; private static bool IsNullKeyDeregisterException(Exception? exception) { if (exception == null) { return false; } if (exception is ArgumentNullException ex && string.Equals(ex.ParamName, "key", StringComparison.OrdinalIgnoreCase)) { return true; } return exception.InnerException != null && IsNullKeyDeregisterException(exception.InnerException); } private static Exception? SwallowNullKeyDeregister(Exception? exception, string source) { if (!IsNullKeyDeregisterException(exception)) { return exception; } if (Interlocked.Exchange(ref _warned, 1) == 0) { Plugin.Log.LogWarning((object)("Suppressed ItemOptimizationManager null-key deregister exception from " + source + ". Rich loot remains enabled; this only prevents isolated null-key optimizer errors from spamming the log.")); } return null; } } public static class RandomEventTask { [CompilerGenerated] private sealed class <RandomEventLoop>d__8 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private int <min>5__1; private int <max>5__2; private int <waitSeconds>5__3; private float <remaining>5__4; private Random <>s__5; private bool <>s__6; private Exception <ex>5__7; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RandomEventLoop>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>s__5 = null; <ex>5__7 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; Plugin.Log.LogInfo((object)"Starting random event coroutine."); goto IL_01bd; case 1: <>1__state = -1; goto IL_015f; case 2: { <>1__state = -1; goto IL_01bd; } IL_01bd: if (Interlocked.CompareExchange(ref ShouldStopTask, 0, 0) != 0 || !PhotonNetwork.IsMasterClient || !Plugin.IsGameplayScene() || !ModConfig.EnableChaosMaster.Value || !ModConfig.EnableRandomEvents.Value) { break; } <min>5__1 = Mathf.Max(1, ModConfig.WaitTimeMin.Value); <max>5__2 = Mathf.Max(<min>5__1, ModConfig.WaitTimeMax.Value); <>s__5 = Rng; <>s__6 = false; try { Monitor.Enter(<>s__5, ref <>s__6); <waitSeconds>5__3 = Rng.Next(<min>5__1, <max>5__2 + 1); } finally { if (<>s__6) { Monitor.Exit(<>s__5); } } <>s__5 = null; <remaining>5__4 = <waitSeconds>5__3; goto IL_015f; IL_015f: if (<remaining>5__4 > 0f) { if (Interlocked.CompareExchange(ref ShouldStopTask, 0, 0) != 0 || !PhotonNetwork.IsMasterClient || !Plugin.IsGameplayScene() || !ModConfig.EnableChaosMaster.Value || !ModConfig.EnableRandomEvents.Value) { _routine = null; RandomizerEvents.ClearPendingQueues(); return false; } <remaining>5__4 -= Time.deltaTime; <>2__current = null; <>1__state = 1; return true; } try { RandomizerEvents.QueueRandomEvent(); } catch (Exception ex) { <ex>5__7 = ex; Plugin.Log.LogError((object)$"Queue random event error: {<ex>5__7}"); } <>2__current = null; <>1__state = 2; return true; } _routine = null; RandomizerEvents.ClearPendingQueues(); Plugin.Log.LogInfo((object)"Stopped random event coroutine."); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static Coroutine? _routine; private static readonly Random Rng = new Random(); public static int ShouldStopTask = 1; public static bool IsRunning => _routine != null; public static void EnsureStarted() { if (PhotonNetwork.IsMasterClient) { if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableRandomEvents.Value) { StopTask(); } else if (_routine == null) { StartTask(); } } } public static void StartTask() { if (PhotonNetwork.IsMasterClient && ModConfig.EnableChaosMaster.Value && ModConfig.EnableRandomEvents.Value && !((Object)(object)Plugin.Instance == (Object)null) && _routine == null) { Interlocked.Exchange(ref ShouldStopTask, 0); RandomizerEvents.SkeletonEventActive = false; _routine = ((MonoBehaviour)Plugin.Instance).StartCoroutine(RandomEventLoop()); } } public static void StopTask() { Interlocked.Exchange(ref ShouldStopTask, 1); if (_routine != null && (Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StopCoroutine(_routine); } _routine = null; RandomizerEvents.ClearPendingQueues(); Plugin.Log.LogInfo((object)"Stopped random event coroutine."); } [IteratorStateMachine(typeof(<RandomEventLoop>d__8))] private static IEnumerator RandomEventLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RandomEventLoop>d__8(0); } } public static class SpecialHeldItemPatch { private static readonly MethodInfo RescueHookLetGoMethod = AccessTools.Method(typeof(RescueHook), "RPCA_LetGo", (Type[])null, (Type[])null); private static bool IsRescueHook(Item item) { return (Object)(object)item != (Object)null && (Object)(object)((Component)item).GetComponent<RescueHook>() != (Object)null; } private static bool IsInfiniteRescueHook(Item item) { return (Object)(object)item != (Object)null && !string.IsNullOrEmpty(((Object)item).name) && ((Object)item).name.Contains("RescueHook_Infinite", StringComparison.OrdinalIgnoreCase); } private static void SafeReleaseRescueHook(Item item) { if (!IsRescueHook(item)) { return; } RescueHook component = ((Component)item).GetComponent<RescueHook>(); if ((Object)(object)component == (Object)null) { return; } try { if (Traverse.Create((object)component).Field("isPulling").GetValue<bool>()) { RescueHookLetGoMethod?.Invoke(component, null); } } catch (Exception arg) { Plugin.Log.LogWarning((object)$"SafeReleaseRescueHook failed: {arg}"); } } [HarmonyPatch(typeof(CharacterItems), "DropItemRpc")] [HarmonyPrefix] private static void PrefixDropItemRpc(CharacterItems __instance) { object obj; if (__instance == null) { obj = null; } else { Character character = __instance.character; if (character == null) { obj = null; } else { CharacterData data = character.data; obj = ((data != null) ? data.currentItem : null); } } Item val = (Item)obj; if ((Object)(object)val != (Object)null) { SafeReleaseRescueHook(val); } } [HarmonyPatch(typeof(CharacterItems), "DestroyHeldItemRpc")] [HarmonyPrefix] private static void PrefixDestroyHeldItemRpc(CharacterItems __instance) { object obj; if (__instance == null) { obj = null; } else { Character character = __instance.character; if (character == null) { obj = null; } else { CharacterData data = character.data; obj = ((data != null) ? data.currentItem : null); } } Item val = (Item)obj; if ((Object)(object)val != (Object)null) { SafeReleaseRescueHook(val); } } [HarmonyPatch(typeof(CharacterItems), "EquipSlot")] [HarmonyPrefix] private static bool PrefixEquipSlot(CharacterItems __instance, Optionable<byte> slotID) { if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.character == (Object)null) { return true; } Item currentItem = __instance.character.data.currentItem; if ((Object)(object)currentItem == (Object)null || !IsInfiniteRescueHook(currentItem)) { return true; } if (!__instance.currentSelectedSlot.IsSome || __instance.currentSelectedSlot.Value != 250) { return true; } if (slotID.IsSome && slotID.Value == 250) { return true; } Plugin.Log.LogInfo((object)"Blocked switching away from temp-slot RescueHook_Infinite to prevent auto-drop crash."); return false; } } public static class RescueHookDestroyPatch { private static readonly MethodInfo RescueHookLetGoMethod = AccessTools.Method(typeof(RescueHook), "RPCA_LetGo", (Type[])null, (Type[])null); [HarmonyPatch(typeof(RescueHook), "OnDestroy")] [HarmonyPrefix] private static void Prefix(RescueHook __instance) { if ((Object)(object)__instance == (Object)null) { return; } try { if (Traverse.Create((object)__instance).Field("isPulling").GetValue<bool>()) { RescueHookLetGoMethod?.Invoke(__instance, null); } } catch (Exception arg) { Plugin.Log.LogWarning((object)$"RescueHook OnDestroy safe release failed: {arg}"); } } } public class ChaosEnvironmentSync : MonoBehaviourPun { private static readonly object MagicBeanVineCleanupLock = new object(); private static readonly List<(Vector3 center, float radius, float cleanupAt)> LocalMagicBeanVineCleanupJobs = new List<(Vector3, float, float)>(); public static ChaosEnvironmentSync Instance { get; private set; } public static bool MesaSunActive { get; private set; } public static float MesaSunRemaining { get; private set; } private void Awake() { Instance = this; } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } MesaSunActive = false; MesaSunRemaining = 0f; ChaosEnvironmentController.RestoreLocalWeatherOverrides(); ClearLocalMagicBeanVineCleanupJobs(); } private void Update() { Ch