Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ToggleQol v0.6.0
BepInEx/plugins/ToggleQol/ToggleQol.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Globalization; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace ToggleQol; internal abstract class QolFeature : IDisposable { private readonly ConfigEntry<bool> setting; private readonly ToggleState state; public string Title { get; private set; } public string Description { get; private set; } public string Status { get; protected set; } public bool Available { get; private set; } public bool Running { get; private set; } public bool Enabled => state.Enabled; protected QolFeature(ConfigFile config, string key, string title, string description) { Title = title; Description = description; setting = config.Bind<bool>("Features", key, true, description); state = new ToggleState(setting.Value, OnToggle); Available = true; Running = true; Status = ""; } public void SetEnabled(bool value) { if (Available && state.Set(value)) { setting.Value = value; } } public virtual void Initialize() { } public void Tick() { if (Available && Running && Enabled) { OnTick(); } } protected virtual void OnTick() { } protected virtual void OnToggle(bool next) { } public void Fail(Exception error) { Available = false; Status = "Unavailable: " + error.Message; Dispose(); } public void Dispose() { if (Running) { Running = false; OnStop(); } } protected virtual void OnStop() { } } internal sealed class AutoDoorsFeature : QolFeature { private sealed class Entry { public bool Opened; public bool SawOpen; public float Requested; public readonly DoorClearance Clearance = new DoorClearance(); public bool ManualOverride; public float ManualUntil; } private static AutoDoorsFeature instance; private Harmony harmony; private static MethodInfo canInteract; private readonly Dictionary<Door, Entry> tracked = new Dictionary<Door, Entry>(); private bool automaticInteraction; private float nextPrune; public AutoDoorsFeature(ConfigFile config) : base(config, "AutoDoors", "Auto-open and close doors", "Open ordinary doors within 2.5 metres. Close only doors opened automatically after all players move 4 metres away. Respects wards; key-locked doors stay manual.") { } public override void Initialize() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown instance = this; canInteract = AccessTools.Method(typeof(Door), "CanInteract", Type.EmptyTypes, (Type[])null); if (canInteract == null) { throw new MissingMethodException("Door.CanInteract changed."); } harmony = new Harmony("benowy.qol.autodoors"); harmony.Patch((MethodBase)AccessTools.Method(typeof(Door), "UpdateState", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(AutoDoorsFeature), "UpdateDoor", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(Door), "Interact", (Type[])null, (Type[])null), new HarmonyMethod(typeof(AutoDoorsFeature), "ManualInteraction", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static void UpdateDoor(Door __instance) { if (instance == null || !instance.Running || !instance.Enabled) { return; } try { instance.Visit(__instance); } catch (Exception error) { instance.Fail(error); } } private static void ManualInteraction(Door __instance) { if (instance != null && instance.Running && instance.Enabled && !instance.automaticInteraction) { instance.tracked[__instance] = new Entry { ManualOverride = true }; } } private void Visit(Door door) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || !Object.op_Implicit((Object)(object)door) || !((Behaviour)door).isActiveAndEnabled || Object.op_Implicit((Object)(object)door.m_keyItem) || door.m_canNotBeClosed) { return; } ZNetView component = ((Component)door).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsValid()) { return; } Vector3 position = ((Component)door).transform.position; float num = Vector3.Distance(((Component)localPlayer).transform.position, position); tracked.TryGetValue(door, out var value); if (num > 12f && value == null) { return; } if (value != null && value.ManualOverride) { if (num < 4f) { return; } tracked.Remove(door); value = null; } if (value != null && Time.time < value.ManualUntil) { return; } int num2 = component.GetZDO().GetInt(ZDOVars.s_state, 0); if ((door.m_checkGuardStone && !PrivateArea.CheckAccess(position, 0f, false, false)) || !(bool)canInteract.Invoke(door, null)) { return; } if (value != null && value.Opened) { if (num2 == 0) { if (value.SawOpen || Time.time - value.Requested > 3f) { tracked[door] = new Entry { ManualUntil = Time.time + 5f }; } return; } value.SawOpen = true; bool occupied = false; foreach (Player allPlayer in Player.GetAllPlayers()) { if (Object.op_Implicit((Object)(object)allPlayer) && !((Character)allPlayer).IsDead() && Vector3.Distance(((Component)allPlayer).transform.position, position) < 4f) { occupied = true; break; } } if (num > 12f) { tracked.Remove(door); } else if (value.Clearance.Ready(occupied, Time.time)) { Use(door, localPlayer); tracked[door] = new Entry { ManualUntil = Time.time + 3f }; } } else { if (num2 != 0 || num > 2.5f || ((Character)localPlayer).IsAttached()) { return; } foreach (Player allPlayer2 in Player.GetAllPlayers()) { if (Object.op_Implicit((Object)(object)allPlayer2) && !((Object)(object)allPlayer2 == (Object)(object)localPlayer) && !((Character)allPlayer2).IsDead()) { float num3 = Vector3.Distance(((Component)allPlayer2).transform.position, position); if (num3 < num || (Mathf.Approximately(num3, num) && allPlayer2.GetPlayerID() < localPlayer.GetPlayerID())) { return; } } } tracked[door] = new Entry { Opened = true, Requested = Time.time }; Use(door, localPlayer); } } private void Use(Door door, Player player) { automaticInteraction = true; try { door.Interact((Humanoid)(object)player, false, false); } finally { automaticInteraction = false; } } protected override void OnTick() { if (Time.time < nextPrune) { return; } nextPrune = Time.time + 5f; List<Door> list = new List<Door>(); foreach (KeyValuePair<Door, Entry> item in tracked) { if (!Object.op_Implicit((Object)(object)item.Key) || (!item.Value.ManualOverride && !item.Value.Opened && Time.time > item.Value.ManualUntil)) { list.Add(item.Key); } } foreach (Door item2 in list) { tracked.Remove(item2); } } protected override void OnToggle(bool next) { if (!next) { tracked.Clear(); } } protected override void OnStop() { if (harmony != null) { harmony.UnpatchSelf(); } tracked.Clear(); } } internal sealed class AutoRunFeature : QolFeature { private static AutoRunFeature instance; private Harmony harmony; private static MethodInfo takeInput; public AutoRunFeature(ConfigFile config) : base(config, "AutoRunSteering", "Auto-run camera steering", "Steer auto-run by turning the camera and keep auto-running when jumping. Movement, attacks and dodging still cancel normally.") { } public override void Initialize() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown instance = this; takeInput = AccessTools.Method(typeof(Player), "TakeInput", Type.EmptyTypes, (Type[])null); if (takeInput == null || AccessTools.Field(typeof(Character), "m_moveDir") == null) { throw new MissingMemberException("Auto-run input fields changed."); } harmony = new Harmony("benowy.qol.autorun"); Harmony obj = harmony; MethodInfo methodInfo = AccessTools.Method(typeof(Player), "SetControls", (Type[])null, (Type[])null); HarmonyMethod val = new HarmonyMethod(typeof(AutoRunFeature), "KeepJumpRunning", (Type[])null); obj.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(AutoRunFeature), "Steer", (Type[])null), val, (HarmonyMethod)null, (HarmonyMethod)null); } private static bool JumpCancels(bool jump, Player player, bool block, bool blockHold) { if (jump) { if (!block && !blockHold && instance != null && instance.Running && instance.Enabled && (Object)(object)player == (Object)(object)Player.m_localPlayer && !((Character)player).IsBlocking() && !((Character)player).IsCrouching() && !((Character)player).IsAttached()) { return player.GetDoodadController() != null; } return true; } return false; } private static IEnumerable<CodeInstruction> KeepJumpRunning(IEnumerable<CodeInstruction> instructions, MethodBase __originalMethod) { //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); int num = Array.FindIndex(__originalMethod.GetParameters(), (ParameterInfo p) => p.Name == "jump") + 1; int num2 = Array.FindIndex(__originalMethod.GetParameters(), (ParameterInfo p) => p.Name == "dodge") + 1; int num3 = Array.FindIndex(__originalMethod.GetParameters(), (ParameterInfo p) => p.Name == "block") + 1; int num4 = Array.FindIndex(__originalMethod.GetParameters(), (ParameterInfo p) => p.Name == "blockHold") + 1; if (num < 1 || num2 < 1 || num3 < 1 || num4 < 1) { throw new MissingMemberException("Control parameters changed."); } int num5 = 0; for (int num6 = 1; num6 + 2 < list.Count; num6++) { if (CodeInstructionExtensions.IsLdarg(list[num6 - 1], (int?)2) && CodeInstructionExtensions.IsLdarg(list[num6], (int?)num) && !(list[num6 + 1].opcode != OpCodes.Or) && CodeInstructionExtensions.IsLdarg(list[num6 + 2], (int?)num2)) { list.Insert(num6 + 1, new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list.Insert(num6 + 2, new CodeInstruction(OpCodes.Ldarg, (object)num3)); list.Insert(num6 + 3, new CodeInstruction(OpCodes.Ldarg, (object)num4)); list.Insert(num6 + 4, new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(AutoRunFeature), "JumpCancels", (Type[])null, (Type[])null))); num5++; num6 += 4; } } if (num5 != 1) { throw new InvalidOperationException("Auto-run jump cancellation site changed."); } return list; } private static void Steer(Player __instance, ref Vector3 ___m_moveDir) { //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_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) if (instance == null || !instance.Running || !instance.Enabled || (Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } try { if (__instance.m_autoRun && !((Character)__instance).IsDead() && !((Character)__instance).IsAttached() && __instance.GetDoodadController() == null && (bool)takeInput.Invoke(__instance, null)) { Vector3 lookDir = ((Character)__instance).GetLookDir(); lookDir.y = 0f; if (((Vector3)(ref lookDir)).sqrMagnitude > 0.0001f) { ___m_moveDir = ((Vector3)(ref lookDir)).normalized; } } } catch (Exception error) { instance.Fail(error); } } protected override void OnStop() { if (harmony != null) { harmony.UnpatchSelf(); } } } internal sealed class BuildSearchFixFeature : QolFeature { private static BuildSearchFixFeature instance; private static FieldInfo searchField; private Harmony harmony; public BuildSearchFixFeature(ConfigFile config) : base(config, "BuildSearchTypingFix", "Fix: build-menu search typing", "Typing B (or your rebound build-menu key) in the search box no longer closes the build menu. Escape still closes it.") { } public override void Initialize() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown instance = this; searchField = AccessTools.Field(typeof(BuildUi), "m_searchField"); MethodInfo methodInfo = AccessTools.Method(typeof(BuildUi), "NavigationUpdate", Type.EmptyTypes, (Type[])null); if (searchField == null || !typeof(TMP_InputField).IsAssignableFrom(searchField.FieldType) || methodInfo == null) { throw new MissingMemberException("Build-menu search input changed."); } harmony = new Harmony("benowy.qol.buildsearchfix"); harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(BuildSearchFixFeature), "ProtectSearch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); } private static bool ReadBuildMenuButton(string button, BuildUi ui) { if (instance != null && instance.Running && instance.Enabled && Object.op_Implicit((Object)(object)ui)) { object? value = searchField.GetValue(ui); TMP_InputField val = (TMP_InputField)((value is TMP_InputField) ? value : null); if (Object.op_Implicit((Object)(object)val) && ((Behaviour)val).isActiveAndEnabled && val.isFocused) { return false; } } return ZInput.GetButtonDown(button); } private static IEnumerable<CodeInstruction> ProtectSearch(IEnumerable<CodeInstruction> instructions) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo methodInfo = AccessTools.Method(typeof(ZInput), "GetButtonDown", new Type[1] { typeof(string) }, (Type[])null); int num = 0; for (int i = 1; i < list.Count; i++) { if (CodeInstructionExtensions.Calls(list[i], methodInfo) && !(list[i - 1].opcode != OpCodes.Ldstr) && object.Equals(list[i - 1].operand, "BuildMenu")) { num++; CodeInstruction val = new CodeInstruction(OpCodes.Ldarg_0, (object)null); val.labels.AddRange(list[i].labels); list[i].labels.Clear(); val.blocks.AddRange(list[i].blocks); list[i].blocks.Clear(); list.Insert(i++, val); list[i].opcode = OpCodes.Call; list[i].operand = AccessTools.Method(typeof(BuildSearchFixFeature), "ReadBuildMenuButton", (Type[])null, (Type[])null); } } if (num != 1) { throw new InvalidOperationException("Expected one build-menu close shortcut; found " + num); } return list; } protected override void OnStop() { if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class ClockTime { public static string Format(float dayFraction) { return Format(dayFraction, useAmPm: false); } public static string Format(float dayFraction, bool useAmPm) { if (float.IsNaN(dayFraction) || float.IsInfinity(dayFraction)) { return "--:--"; } double num = (double)dayFraction - Math.Floor(dayFraction); int num2 = (int)Math.Floor(num * 48.0) * 30; if (useAmPm) { int num3 = num2 / 60 % 12; return ((num3 == 0) ? 12 : num3).ToString(CultureInfo.InvariantCulture) + ":" + (num2 % 60).ToString("00", CultureInfo.InvariantCulture) + ((num2 < 720) ? " AM" : " PM"); } return (num2 / 60).ToString("00", CultureInfo.InvariantCulture) + ":" + (num2 % 60).ToString("00", CultureInfo.InvariantCulture); } } internal sealed class CrossbowReloadFeature : QolFeature { private static CrossbowReloadFeature instance; private static FieldInfo queue; private static MethodInfo clearQueue; private Harmony harmony; public CrossbowReloadFeature(ConfigFile config) : base(config, "MobileCrossbowReload", "Reload crossbows on the move", "Reload crossbows while sprinting or jumping. Normal reload time, stamina and ammo requirements apply. Dodging and switching weapons still interrupt reloading.") { } public override void Initialize() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown instance = this; clearQueue = AccessTools.Method(typeof(Humanoid), "ClearActionQueue", Type.EmptyTypes, (Type[])null); if (clearQueue == null) { throw new MissingMethodException("ClearActionQueue changed."); } queue = AccessTools.Field(typeof(Player), "m_actionQueue"); if (queue == null || queue.FieldType != typeof(List<MinorActionData>)) { throw new MissingMemberException("Reload queue changed."); } harmony = new Harmony("benowy.qol.crossbowreload"); string[] array = new string[2] { "CheckRun", "OnJump" }; foreach (string text in array) { harmony.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Player), text, (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(CrossbowReloadFeature), "KeepReload", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); } harmony.Patch((MethodBase)AccessTools.Method(typeof(Player), "InMinorActionSlowdown", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(CrossbowReloadFeature), "AllowMovement", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static bool Eligible(Player player) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Invalid comparison between Unknown and I4 //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Invalid comparison between Unknown and I4 if (instance == null || !instance.Running || !instance.Enabled || !Object.op_Implicit((Object)(object)player) || (Object)(object)player != (Object)(object)Player.m_localPlayer || ((Character)player).IsDead()) { return false; } List<MinorActionData> list = (List<MinorActionData>)queue.GetValue(player); if (list.Count != 1 || (int)list[0].m_type != 2) { return false; } ItemData item = list[0].m_item; if (item != null && item == ((Humanoid)player).GetCurrentWeapon() && (int)item.m_shared.m_skillType == 14) { return item.m_shared.m_attack.m_requiresReload; } return false; } private static void ClearUnlessReloading(Humanoid human) { if (!Eligible((Player)(object)((human is Player) ? human : null))) { clearQueue.Invoke(human, null); } } private static void AllowMovement(Player __instance, ref bool __result) { if (__result && Eligible(__instance)) { __result = false; } } private static IEnumerable<CodeInstruction> KeepReload(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo methodInfo = AccessTools.Method(typeof(Humanoid), "ClearActionQueue", Type.EmptyTypes, (Type[])null); int num = 0; foreach (CodeInstruction item in list) { if (CodeInstructionExtensions.Calls(item, methodInfo)) { item.opcode = OpCodes.Call; item.operand = AccessTools.Method(typeof(CrossbowReloadFeature), "ClearUnlessReloading", (Type[])null, (Type[])null); num++; } } if (num != 1) { throw new InvalidOperationException("Expected exactly one movement queue-clear site."); } return list; } protected override void OnStop() { if (harmony != null) { harmony.UnpatchSelf(); } } } internal sealed class DoorClearance { private float clearSince = -1f; public bool Ready(bool occupied, float now) { if (occupied) { clearSince = -1f; return false; } if (clearSince < 0f || now < clearSince) { clearSince = now; return false; } return now - clearSince >= 1f; } } internal static class FoodFactorPolicy { public static float Apply(float nativeFactor, bool active) { if (!active || !(nativeFactor > 0f)) { return nativeFactor; } return 1f; } } internal sealed class FullFoodFeature : QolFeature { private const string Id = "benowy.qol.food"; private static FullFoodFeature instance; private Harmony harmony; public FullFoodFeature(ConfigFile config) : base(config, "FullDurationFood", "Full-duration food", "Personal: full food health, stamina and Eitr benefits until normal expiry. Changes apply on the next normal food tick; timers and regeneration stay normal.") { } public override void Initialize() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown instance = this; harmony = new Harmony("benowy.qol.food"); MethodInfo methodInfo = AccessTools.Method(typeof(Player), "UpdateFood", new Type[2] { typeof(float), typeof(bool) }, (Type[])null); if (methodInfo == null) { throw new MissingMethodException("Player.UpdateFood changed."); } harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(FullFoodFeature), "RemoveDecay", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); } private static float AdjustFactor(float nativeFactor, Player player) { bool active = instance != null && instance.Running && instance.Available && instance.Enabled && Object.op_Implicit((Object)(object)player) && (Object)(object)player == (Object)(object)Player.m_localPlayer; return FoodFactorPolicy.Apply(nativeFactor, active); } private static IEnumerable<CodeInstruction> RemoveDecay(IEnumerable<CodeInstruction> instructions) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); int num = -1; for (int i = 11; i + 25 < list.Count; i++) { if (MatchesDecay(list, i)) { if (num >= 0) { throw new InvalidOperationException("Multiple food-decay sites; refusing an ambiguous patch."); } num = i; } } if (num < 0) { throw new InvalidOperationException("Expected food-decay calculation not found; game or another food mod changed it."); } list.Insert(num + 1, new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list.Insert(num + 2, new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(FullFoodFeature), "AdjustFactor", (Type[])null, (Type[])null))); return list; } private static bool MatchesDecay(List<CodeInstruction> code, int i) { if (!Calls(code[i], typeof(Mathf), "Pow") || code[i - 1].opcode != OpCodes.Ldc_R4 || !(code[i - 1].operand is float) || (float)code[i - 1].operand != 0.3f || !Calls(code[i - 4], typeof(Mathf), "Clamp01") || code[i - 5].opcode != OpCodes.Div || !Field(code[i - 6], OpCodes.Ldfld, typeof(SharedData), "m_foodBurnTime") || !Field(code[i - 10], OpCodes.Ldfld, typeof(Food), "m_time")) { return false; } int num = Local(code[i + 1], store: true); if (num < 0 || Local(code[i - 3], store: true) != num || Local(code[i - 2], store: false) != num) { return false; } string[] array = new string[3] { "m_food", "m_foodStamina", "m_foodEitr" }; string[] array2 = new string[3] { "m_health", "m_stamina", "m_eitr" }; for (int j = 0; j < 3; j++) { int num2 = i + j * 8; if (!Field(code[num2 + 6], OpCodes.Ldfld, typeof(SharedData), array[j]) || Local(code[num2 + 7], store: false) != num || code[num2 + 8].opcode != OpCodes.Mul || !Field(code[num2 + 9], OpCodes.Stfld, typeof(Food), array2[j])) { return false; } } return true; } private static bool Calls(CodeInstruction instruction, Type type, string name) { MethodInfo methodInfo = instruction.operand as MethodInfo; if (instruction.opcode == OpCodes.Call && methodInfo != null && methodInfo.DeclaringType == type) { return methodInfo.Name == name; } return false; } private static bool Field(CodeInstruction instruction, OpCode opcode, Type type, string name) { FieldInfo fieldInfo = instruction.operand as FieldInfo; if (instruction.opcode == opcode && fieldInfo != null && fieldInfo.DeclaringType == type) { return fieldInfo.Name == name; } return false; } private static int Local(CodeInstruction instruction, bool store) { OpCode opcode = instruction.opcode; if (opcode == (store ? OpCodes.Stloc_0 : OpCodes.Ldloc_0)) { return 0; } if (opcode == (store ? OpCodes.Stloc_1 : OpCodes.Ldloc_1)) { return 1; } if (opcode == (store ? OpCodes.Stloc_2 : OpCodes.Ldloc_2)) { return 2; } if (opcode == (store ? OpCodes.Stloc_3 : OpCodes.Ldloc_3)) { return 3; } if (opcode != (store ? OpCodes.Stloc : OpCodes.Ldloc) && opcode != (store ? OpCodes.Stloc_S : OpCodes.Ldloc_S)) { return -1; } if (!(instruction.operand is LocalBuilder localBuilder)) { return Convert.ToInt32(instruction.operand); } return localBuilder.LocalIndex; } protected override void OnStop() { if (harmony != null) { harmony.UnpatchSelf(); } if (instance == this) { instance = null; } } } internal sealed class InputGuard : IDisposable { private Harmony harmony; private static InputGuard current; private readonly MenuInputState state = new MenuInputState(); private KeyCode releaseKey; private static bool readingMenuInput; public bool Blocking => state.Blocking; private static bool Block { get { if (current != null && current.Blocking) { return !readingMenuInput; } return false; } } public void Install() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown current = this; harmony = new Harmony("benowy.qol.menu"); Patch(typeof(Player), "TakeInput", Type.EmptyTypes, "BlockBoolean"); Patch(typeof(PlayerController), "TakeInput", new Type[1] { typeof(bool) }, "BlockBoolean"); Patch(typeof(GameCamera), "UpdateMouseCapture", Type.EmptyTypes, "CaptureCursor"); string[] array = new string[3] { "GetButton", "GetButtonDown", "GetButtonUp" }; foreach (string method in array) { Patch(typeof(ZInput), method, new Type[1] { typeof(string) }, "BlockBoolean"); } string[] array2 = new string[3] { "GetMouseButton", "GetMouseButtonDown", "GetMouseButtonUp" }; foreach (string method2 in array2) { Patch(typeof(ZInput), method2, new Type[1] { typeof(int) }, "BlockBoolean"); } string[] array3 = new string[3] { "GetKey", "GetKeyDown", "GetKeyUp" }; foreach (string method3 in array3) { Patch(typeof(ZInput), method3, new Type[2] { typeof(KeyCode), typeof(bool) }, "BlockBoolean"); } string[] array4 = new string[4] { "GetJoyLeftStickX", "GetJoyLeftStickY", "GetJoyRightStickX", "GetJoyRightStickY" }; foreach (string name in array4) { PatchStick(name, typeof(float), "BlockFloat"); } string[] array5 = new string[2] { "GetJoyLeftStick", "GetJoyRightStick" }; foreach (string name2 in array5) { PatchStick(name2, typeof(Vector2), "BlockVector"); } string[] array6 = new string[3] { "GetMouseScrollWheel", "GetJoyLTrigger", "GetJoyRTrigger" }; foreach (string method4 in array6) { Patch(typeof(ZInput), method4, Type.EmptyTypes, "BlockFloat"); } Patch(typeof(ZInput), "GetMouseDelta", Type.EmptyTypes, "BlockVector"); } private void PatchStick(string name, Type result, string prefix) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown int num = 0; MethodInfo[] methods = typeof(ZInput).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != name) && !(methodInfo.ReturnType != result)) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 0 || (parameters.Length == 1 && parameters[0].ParameterType == typeof(bool))) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(InputGuard), prefix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); num++; } } } if (num == 0) { throw new MissingMethodException("No supported controller input method: ZInput." + name); } } private void Patch(Type type, string method, Type[] args, string prefix) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(type, method, args, (Type[])null); if (methodInfo == null) { throw new MissingMethodException(type.Name, method); } harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(InputGuard), prefix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public bool KeyDown(KeyCode key) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) readingMenuInput = true; try { return ZInput.GetKeyDown(key, true); } finally { readingMenuInput = false; } } public void SetOpen(bool value, KeyCode key) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) state.SetOpen(value, Time.unscaledTime); if (value) { Unlock(); return; } releaseKey = key; PlayerController.SetTakeInputDelay(0.2f); ZInput.IgnoreMouseInputForFrames(2); } public void Update() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (state.Open) { Unlock(); } else if (state.Blocking) { readingMenuInput = true; try { bool closingInputHeld = ZInput.GetKey(releaseKey, true) || ZInput.GetKey((KeyCode)27, true) || ZInput.GetMouseButton(0) || ZInput.GetMouseButton(1) || ZInput.GetMouseButton(2) || ZInput.GetButton("Attack") || ZInput.GetButton("SecondaryAttack") || ZInput.GetJoyLTrigger() > 0.2f || ZInput.GetJoyRTrigger() > 0.2f; state.Update(Time.unscaledTime, closingInputHeld); } finally { readingMenuInput = false; } } } private static void Unlock() { ZCursor.LockState = (CursorLockMode)0; ZCursor.Show(); } private static bool CaptureCursor() { if (!Block) { return true; } Unlock(); return false; } private static bool BlockBoolean(ref bool __result) { if (!Block) { return true; } __result = false; return false; } private static bool BlockFloat(ref float __result) { if (!Block) { return true; } __result = 0f; return false; } private static bool BlockVector(ref Vector2 __result) { //IL_000a: 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) if (!Block) { return true; } __result = Vector2.zero; return false; } public void Dispose() { state.Reset(); if (harmony != null) { harmony.UnpatchSelf(); harmony = null; } if (current == this) { current = null; } } } internal sealed class MenuInputState { private bool pending; private float releaseAfter; public bool Open { get; private set; } public bool Blocking { get { if (!Open) { return pending; } return true; } } public void SetOpen(bool value, float now) { Open = value; pending = !value; releaseAfter = now + 0.2f; } public void Update(float now, bool closingInputHeld) { if (!Open && pending && now >= releaseAfter && !closingInputHeld) { pending = false; } } public void Reset() { Open = false; pending = false; } } internal sealed class MinimapClockFeature : QolFeature { private TextMeshProUGUI label; private TextMeshProUGUI timeLabel; private Minimap owner; private readonly ConfigEntry<bool> useAmPm; public bool UseAmPm => useAmPm.Value; public void ToggleFormat() { useAmPm.Value = !useAmPm.Value; if (base.Enabled && base.Running) { OnTick(); } } public MinimapClockFeature(ConfigFile config) : base(config, "MinimapClock", "Minimap day and time", "In-game day and clock in half-hour steps. Choose 24-hour time or AM/PM using the adjacent button.") { useAmPm = config.Bind<bool>("Clock", "UseAmPm", false, "Use 12-hour AM/PM time instead of 24-hour time."); } protected override void OnTick() { //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Expected O, but got Unknown //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) Minimap instance = Minimap.instance; if ((Object)(object)owner != (Object)(object)instance) { Clear(); } if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)instance.m_smallRoot) || !Object.op_Implicit((Object)(object)instance.m_mapImageSmall) || !Object.op_Implicit((Object)(object)instance.m_biomeNameSmall)) { return; } if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)EnvMan.instance) || !Object.op_Implicit((Object)(object)ZNet.instance) || !Object.op_Implicit((Object)(object)Hud.instance) || !Hud.instance.IsVisible() || !instance.m_smallRoot.activeInHierarchy) { if (Object.op_Implicit((Object)(object)label)) { ((Component)label).gameObject.SetActive(false); } return; } if (!Object.op_Implicit((Object)(object)label)) { owner = instance; GameObject val = new GameObject("ToggleQolClock", new Type[1] { typeof(RectTransform) }); val.SetActive(false); val.transform.SetParent(((Component)instance.m_mapImageSmall).transform, false); label = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)label).font = instance.m_biomeNameSmall.font; ((TMP_Text)label).fontSharedMaterial = instance.m_biomeNameSmall.fontSharedMaterial; ((TMP_Text)label).fontSize = 20f; ((TMP_Text)label).enableAutoSizing = true; ((TMP_Text)label).fontSizeMin = 12f; ((TMP_Text)label).fontSizeMax = 20f; ((TMP_Text)label).fontStyle = (FontStyles)1; ((Graphic)label).color = Color.white; ((TMP_Text)label).alignment = (TextAlignmentOptions)513; ((Graphic)label).raycastTarget = false; ((MaskableGraphic)label).maskable = false; ((TMP_Text)label).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)label).overflowMode = (TextOverflowModes)0; RectTransform rectTransform = ((TMP_Text)label).rectTransform; rectTransform.anchorMin = new Vector2(0f, 1f); rectTransform.anchorMax = new Vector2(1f, 1f); rectTransform.pivot = new Vector2(0.5f, 0f); rectTransform.sizeDelta = new Vector2(-12f, 26f); rectTransform.anchoredPosition = new Vector2(0f, 4f); GameObject val2 = new GameObject("ToggleQolTime", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(val.transform, false); timeLabel = val2.AddComponent<TextMeshProUGUI>(); ((TMP_Text)timeLabel).font = ((TMP_Text)label).font; ((TMP_Text)timeLabel).fontSharedMaterial = ((TMP_Text)label).fontSharedMaterial; ((TMP_Text)timeLabel).fontSize = ((TMP_Text)label).fontSize; ((TMP_Text)timeLabel).enableAutoSizing = true; ((TMP_Text)timeLabel).fontSizeMin = 12f; ((TMP_Text)timeLabel).fontSizeMax = 20f; ((TMP_Text)timeLabel).fontStyle = ((TMP_Text)label).fontStyle; ((Graphic)timeLabel).color = ((Graphic)label).color; ((TMP_Text)timeLabel).alignment = (TextAlignmentOptions)516; ((Graphic)timeLabel).raycastTarget = false; ((MaskableGraphic)timeLabel).maskable = false; ((TMP_Text)timeLabel).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)timeLabel).overflowMode = (TextOverflowModes)0; ((TMP_Text)timeLabel).rectTransform.anchorMin = new Vector2(0.45f, 0f); ((TMP_Text)timeLabel).rectTransform.anchorMax = Vector2.one; ((TMP_Text)timeLabel).rectTransform.offsetMin = Vector2.zero; ((TMP_Text)timeLabel).rectTransform.offsetMax = Vector2.zero; } bool flag = !((Component)label).gameObject.activeSelf; ((Component)label).gameObject.SetActive(true); TextMeshProUGUI obj = label; Rect rect = ((TMP_Text)label).rectTransform.rect; ((TMP_Text)obj).margin = new Vector4(0f, 0f, ((Rect)(ref rect)).width * 0.55f + 6f, 0f); ((TMP_Text)label).text = "Day " + EnvMan.instance.GetDay().ToString(CultureInfo.InvariantCulture); ((TMP_Text)timeLabel).text = ClockTime.Format(EnvMan.instance.GetDayFraction(), UseAmPm); if (flag) { label.canvasRenderer.cull = false; ((Graphic)label).SetAllDirty(); ((TMP_Text)label).ForceMeshUpdate(false, false); timeLabel.canvasRenderer.cull = false; ((Graphic)timeLabel).SetAllDirty(); ((TMP_Text)timeLabel).ForceMeshUpdate(false, false); } } protected override void OnToggle(bool next) { if (next) { OnTick(); } else if (Object.op_Implicit((Object)(object)label)) { ((Component)label).gameObject.SetActive(false); } } protected override void OnStop() { Clear(); } private void Clear() { if (Object.op_Implicit((Object)(object)label)) { ((Component)label).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)label).gameObject); } label = null; timeLabel = null; owner = null; } } internal sealed class OrderedSummonsFeature : QolFeature { private sealed class Cursor { public ConfigEntry<int> Saved; public SummonCycleState State; } private sealed class Ticket { public long Caster; public int SelectedIndex; public GameObject Created; } private static OrderedSummonsFeature instance; private static readonly FieldInfo Owner = AccessTools.Field(typeof(SpawnAbility), "m_owner"); private static readonly FieldInfo Weapon = AccessTools.Field(typeof(SpawnAbility), "m_weapon"); private readonly ConfigFile config; private readonly Action<string> warn; private Harmony harmony; private readonly Dictionary<long, Cursor> cursors = new Dictionary<long, Cursor>(); private readonly Dictionary<SpawnAbility, Ticket> tickets = new Dictionary<SpawnAbility, Ticket>(); private readonly List<SpawnAbility> expired = new List<SpawnAbility>(); public OrderedSummonsFeature(ConfigFile config, Action<string> warn) : base(config, "OrderedSpiritSummons", "Ordered Spirit Caller summons", "Personal cast order: boar > wolf > bear > moose. Advances after a successful spawn; native caps/costs stay normal. Saves per character. In-flight casts finish their selected mode.") { this.config = config; this.warn = warn; } public override void Initialize() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown instance = this; if (Owner == null || Weapon == null) { throw new MissingFieldException("SpawnAbility caster/item fields changed."); } MethodInfo methodInfo = AccessTools.EnumeratorMoveNext((MethodBase)AccessTools.Method(typeof(SpawnAbility), "Spawn", (Type[])null, (Type[])null)); if (methodInfo == null) { throw new MissingMethodException("Spawn coroutine changed."); } harmony = new Harmony("benowy.qol.orderedspirits"); harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(OrderedSummonsFeature), "PatchSpawn", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); } private Cursor GetCursor(long id) { if (!cursors.TryGetValue(id, out var value)) { ConfigEntry<int> val = config.Bind<int>("SpiritCycle", "Character_" + id.ToString(CultureInfo.InvariantCulture), 0, "Next ordered spirit for this character: 0 boar, 1 wolf, 2 bear, 3 moose. Saved after successful ordered spawns; independent of world and army composition."); Cursor cursor = new Cursor(); cursor.Saved = val; cursor.State = new SummonCycleState(val.Value); value = cursor; cursors.Add(id, value); } return value; } private static bool Caster(SpawnAbility ability, out Player player) { player = null; if (!Object.op_Implicit((Object)(object)ability) || PrefabName(((Component)ability).gameObject) != "staff_SpiritCaller_spawn" || ability.m_minToSpawn != 1 || ability.m_maxToSpawn != 1) { return false; } object? value = Owner.GetValue(ability); player = (Player)((value is Player) ? value : null); object? value2 = Weapon.GetValue(ability); ItemData val = (ItemData)((value2 is ItemData) ? value2 : null); if (Object.op_Implicit((Object)(object)player) && (Object)(object)player == (Object)(object)Player.m_localPlayer && player.GetPlayerID() != 0 && val != null && Object.op_Implicit((Object)(object)val.m_dropPrefab)) { return ((Object)val.m_dropPrefab).name == "StaffSpiritCaller"; } return false; } private static GameObject[] Prefabs(SpawnAbility ability) { if (ability.m_spawnPrefab == null || ability.m_spawnPrefab.Length != 4) { return null; } GameObject[] array = (GameObject[])(object)new GameObject[4]; GameObject[] spawnPrefab = ability.m_spawnPrefab; foreach (GameObject val in spawnPrefab) { if (!Object.op_Implicit((Object)(object)val)) { return null; } int num = Array.IndexOf(SummonCycleState.PrefabOrder, ((Object)val).name); if (num < 0 || Object.op_Implicit((Object)(object)array[num])) { return null; } array[num] = val; } return array; } private static string PrefabName(GameObject obj) { string name = ((Object)obj).name; if (!name.EndsWith("(Clone)", StringComparison.Ordinal)) { return name; } return name.Substring(0, name.Length - 7); } private static GameObject Select(GameObject nativeRandom, SpawnAbility ability) { OrderedSummonsFeature orderedSummonsFeature = instance; if (orderedSummonsFeature == null || !orderedSummonsFeature.Running || !orderedSummonsFeature.Available) { return nativeRandom; } orderedSummonsFeature.Prune(); orderedSummonsFeature.tickets.Remove(ability); if (!orderedSummonsFeature.Enabled) { return nativeRandom; } try { if (!Caster(ability, out var player)) { return nativeRandom; } GameObject[] array = Prefabs(ability); if (array == null) { return nativeRandom; } long playerID = player.GetPlayerID(); int nextIndex = orderedSummonsFeature.GetCursor(playerID).State.NextIndex; orderedSummonsFeature.tickets[ability] = new Ticket { Caster = playerID, SelectedIndex = nextIndex }; return array[nextIndex]; } catch (Exception ex) { orderedSummonsFeature.warn("Ordered selection skipped: " + ex.Message); return nativeRandom; } } private static GameObject Create(GameObject selected, Vector3 position, Quaternion rotation, SpawnAbility ability, Vector3 target) { //IL_010a: 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_009e: Unknown result type (might be due to invalid IL or missing references) OrderedSummonsFeature orderedSummonsFeature = instance; Ticket value = null; GameObject val = selected; if (orderedSummonsFeature != null && orderedSummonsFeature.Running && orderedSummonsFeature.Available && orderedSummonsFeature.tickets.TryGetValue(ability, out value)) { try { GameObject[] array = Prefabs(ability); if (!Caster(ability, out var player) || player.GetPlayerID() != value.Caster || array == null) { orderedSummonsFeature.tickets.Remove(ability); value = null; } else { value.SelectedIndex = orderedSummonsFeature.GetCursor(value.Caster).State.NextIndex; val = array[value.SelectedIndex]; if (ability.m_maxSpawned > 0 && SpawnSystem.GetNrOfInstances(val, target, 0f, false, false) >= ability.m_maxSpawned) { orderedSummonsFeature.tickets.Remove(ability); ((Character)player).Message((MessageType)2, ability.m_maxSummonReached, 0, (Sprite)null, false); return null; } } } catch (Exception ex) { orderedSummonsFeature.tickets.Remove(ability); value = null; val = selected; orderedSummonsFeature.warn("Ordered spawn preparation skipped: " + ex.Message); } } GameObject val2 = Object.Instantiate<GameObject>(val, position, rotation); if (value != null) { value.Created = val2; } return val2; } private static void Commit(GameObject created, SpawnAbility ability) { OrderedSummonsFeature orderedSummonsFeature = instance; if (orderedSummonsFeature == null || !orderedSummonsFeature.tickets.TryGetValue(ability, out var value)) { return; } orderedSummonsFeature.tickets.Remove(ability); try { if (!Object.op_Implicit((Object)(object)created) || (Object)(object)created != (Object)(object)value.Created || !Object.op_Implicit((Object)(object)created.GetComponent<Character>()) || PrefabName(created) != SummonCycleState.PrefabOrder[value.SelectedIndex]) { return; } ZNetView component = created.GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsValid()) { return; } Cursor cursor = orderedSummonsFeature.GetCursor(value.Caster); if (!cursor.State.Commit(value.SelectedIndex)) { orderedSummonsFeature.warn("Ordered cycle changed unexpectedly during spawn; cursor was not advanced."); return; } cursor.Saved.Value = cursor.State.NextIndex; try { orderedSummonsFeature.config.Save(); } catch (Exception ex) { orderedSummonsFeature.warn("Cycle advanced for this session, but could not save: " + ex.Message); } } catch (Exception ex2) { orderedSummonsFeature.warn("Could not record successful ordered spawn: " + ex2.Message); } } protected override void OnTick() { Prune(); } private void Prune() { expired.Clear(); foreach (KeyValuePair<SpawnAbility, Ticket> ticket in tickets) { if (!Object.op_Implicit((Object)(object)ticket.Key)) { expired.Add(ticket.Key); } } foreach (SpawnAbility item in expired) { tickets.Remove(item); } } protected override void OnStop() { if (harmony != null) { harmony.UnpatchSelf(); } tickets.Clear(); if (instance == this) { instance = null; } } private static IEnumerable<CodeInstruction> PatchSpawn(IEnumerable<CodeInstruction> instructions, MethodBase original, ILGenerator generator) { //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Expected O, but got Unknown //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Expected O, but got Unknown //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Expected O, but got Unknown //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Expected O, but got Unknown //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_0462: Expected O, but got Unknown //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Expected O, but got Unknown //IL_0491: Unknown result type (might be due to invalid IL or missing references) //IL_049b: Expected O, but got Unknown //IL_04a9: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Expected O, but got Unknown //IL_04c1: Unknown result type (might be due to invalid IL or missing references) //IL_04cb: Expected O, but got Unknown //IL_04d3: Unknown result type (might be due to invalid IL or missing references) //IL_04dd: Expected O, but got Unknown //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_04f0: Expected O, but got Unknown //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_0508: Expected O, but got Unknown //IL_0510: Unknown result type (might be due to invalid IL or missing references) //IL_051a: Expected O, but got Unknown //IL_0522: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Expected O, but got Unknown //IL_0549: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); FieldInfo fieldInfo = AccessTools.Field(original.DeclaringType, "<>4__this"); FieldInfo fieldInfo2 = AccessTools.Field(original.DeclaringType, "<targetPosition>5__5"); int num = -1; int num2 = -1; int num3 = -1; object obj = null; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; for (int i = 1; i + 1 < list.Count; i++) { MethodInfo methodInfo = list[i].operand as MethodInfo; FieldInfo fieldInfo3 = list[i].operand as FieldInfo; if (list[i].opcode == OpCodes.Ldelem_Ref && CodeInstructionExtensions.Calls(list[i - 1], AccessTools.Method(typeof(Random), "Range", new Type[2] { typeof(int), typeof(int) }, (Type[])null)) && list[i + 1].opcode == OpCodes.Stfld && ((FieldInfo)list[i + 1].operand).Name == "<prefab>5__9") { num = i; num4++; } if (list[i].opcode == OpCodes.Call && methodInfo != null && methodInfo.DeclaringType == typeof(Object) && methodInfo.Name == "Instantiate" && methodInfo.IsGenericMethod && methodInfo.GetGenericArguments()[0] == typeof(GameObject) && methodInfo.GetParameters().Length == 3) { num2 = i; num5++; } if (fieldInfo3 != null && fieldInfo3.DeclaringType == typeof(SpawnAbility) && fieldInfo3.Name == "m_preSpawnEffects" && i >= 2 && (list[i - 2].opcode == OpCodes.Br || list[i - 2].opcode == OpCodes.Br_S)) { obj = list[i - 2].operand; num7++; } if (fieldInfo3 != null && fieldInfo3.DeclaringType == typeof(SpawnAbility) && fieldInfo3.Name == "m_spawnDelay" && i >= 3 && list[i - 2].opcode == OpCodes.Pop && list[i - 3].operand is MethodInfo && ((MethodInfo)list[i - 3].operand).DeclaringType == typeof(EffectList) && ((MethodInfo)list[i - 3].operand).Name == "Create") { num3 = i - 2; num6++; } } if (fieldInfo == null || fieldInfo2 == null || num4 != 1 || num5 != 1 || num6 != 1 || num7 != 1 || num >= num2 || num2 >= num3 || !(obj is Label) || list[num2 + 1].opcode != OpCodes.Stloc_2 || list[num2].labels.Count != 0 || list[num2].blocks.Count != 0) { throw new InvalidOperationException("Spirit spawn structure changed; ordered feature not patched."); } Label label = generator.DefineLabel(); list[num2 + 1].labels.Add(label); List<CodeInstruction> list2 = new List<CodeInstruction>(); for (int j = 0; j < list.Count; j++) { if (j == num2) { list2.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list2.Add(new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo)); list2.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list2.Add(new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo2)); list[j].operand = AccessTools.Method(typeof(OrderedSummonsFeature), "Create", (Type[])null, (Type[])null); } list2.Add(list[j]); if (j == num) { list2.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list2.Add(new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo)); list2.Add(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(OrderedSummonsFeature), "Select", (Type[])null, (Type[])null))); } if (j == num2) { list2.Add(new CodeInstruction(OpCodes.Dup, (object)null)); list2.Add(new CodeInstruction(OpCodes.Brtrue, (object)label)); list2.Add(new CodeInstruction(OpCodes.Pop, (object)null)); list2.Add(new CodeInstruction(OpCodes.Br, obj)); } if (j == num3) { list2.Add(new CodeInstruction(OpCodes.Ldloc_2, (object)null)); list2.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list2.Add(new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo)); list2.Add(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(OrderedSummonsFeature), "Commit", (Type[])null, (Type[])null))); } } return list2; } } [BepInIncompatibility("local.food.fullduration")] [DefaultExecutionOrder(-10000)] [BepInPlugin("benowy.qol", "ToggleQol", "0.6.0")] [BepInIncompatibility("local.spiritcaller.passthrough")] public sealed class Plugin : BaseUnityPlugin { public const string Id = "benowy.qol"; private readonly List<QolFeature> features = new List<QolFeature>(); private ConfigEntry<KeyCode> menuKey; private SettingsMenu menu; private InputGuard input; private bool ready; private void Awake() { //IL_0037: 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_004b: Invalid comparison between Unknown and I4 ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; menuKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Menu", "Hotkey", (KeyCode)289, "Keyboard key for the ToggleQol menu. Also changeable in-game. Default F8."); if ((int)menuKey.Value == 0 || (int)menuKey.Value == 27) { menuKey.Value = (KeyCode)289; } features.Add(new SpiritCollisionFeature(((BaseUnityPlugin)this).Config)); features.Add(new FullFoodFeature(((BaseUnityPlugin)this).Config)); features.Add(new MinimapClockFeature(((BaseUnityPlugin)this).Config)); features.Add(new AutoDoorsFeature(((BaseUnityPlugin)this).Config)); features.Add(new AutoRunFeature(((BaseUnityPlugin)this).Config)); features.Add(new CrossbowReloadFeature(((BaseUnityPlugin)this).Config)); features.Add(new SwimmingToolsFeature(((BaseUnityPlugin)this).Config)); features.Add(new OrderedSummonsFeature(((BaseUnityPlugin)this).Config, delegate(string message) { ((BaseUnityPlugin)this).Logger.LogWarning((object)message); })); features.Add(new BuildSearchFixFeature(((BaseUnityPlugin)this).Config)); foreach (QolFeature feature in features) { try { feature.Initialize(); } catch (Exception ex) { feature.Fail(ex); ((BaseUnityPlugin)this).Logger.LogError((object)(feature.Title + ": " + ex)); } } try { input = new InputGuard(); input.Install(); menu = new SettingsMenu(features, menuKey, SaveSettings, input); } catch (Exception ex2) { if (input != null) { input.Dispose(); } ((BaseUnityPlugin)this).Logger.LogError((object)("Menu input protection could not initialize; menu disabled. Features remain configurable in benowy.qol.cfg. " + ex2)); } ready = true; SaveSettings(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ToggleQol ready. F8 by default opens settings in-game. Collision requires matching settings on every client and dedicated server; food is personal."); } private string SaveSettings() { try { ((BaseUnityPlugin)this).Config.Save(); return "Saved. Food changes apply on the next normal food tick."; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Settings active but could not save: " + ex.Message)); return "Active, but could not save settings: " + ex.Message; } } private void Update() { if (ready && menu != null) { menu.Update(); } } private void FixedUpdate() { if (!ready) { return; } foreach (QolFeature feature in features) { try { feature.Tick(); } catch (Exception ex) { feature.Fail(ex); ((BaseUnityPlugin)this).Logger.LogError((object)(feature.Title + " stopped safely: " + ex)); } } } private void OnGUI() { if (ready && menu != null) { menu.Draw(); } } private void OnDisable() { ready = false; if (menu != null) { menu.Dispose(); } if (input != null) { input.Dispose(); } foreach (QolFeature feature in features) { feature.Dispose(); } } private void OnDestroy() { OnDisable(); } } internal sealed class SettingsMenu : IDisposable { private readonly List<QolFeature> features; private readonly ConfigEntry<KeyCode> hotkey; private readonly Func<string> save; private readonly InputGuard input; private readonly UiShield shield = new UiShield(); private bool open; private bool capturing; private Player menuPlayer; private string status = "Changes save automatically"; private Rect window; private Vector2 scroll; private GUIStyle windowStyle; private GUIStyle titleStyle; private GUIStyle labelStyle; private GUIStyle headingStyle; private GUIStyle nameStyle; private GUIStyle buttonStyle; private GUIStyle smallStyle; private GUIStyle stateStyle; private Texture2D background; private Texture2D pill; private Texture2D knob; private Texture2D buttonTexture; private Texture2D hoverTexture; private Texture2D selectedTexture; private readonly Color gold = new Color(0.76f, 0.59f, 0.34f); private readonly Color teal = new Color(0.3f, 0.78f, 0.7f); private readonly Color muted = new Color(0.61f, 0.67f, 0.68f); public SettingsMenu(List<QolFeature> features, ConfigEntry<KeyCode> hotkey, Func<string> save, InputGuard input) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) this.features = new List<QolFeature>(features); this.features.Sort((QolFeature a, QolFeature b) => Order(a).CompareTo(Order(b))); this.hotkey = hotkey; this.save = save; this.input = input; } private static int Order(QolFeature f) { if (f is CrossbowReloadFeature) { return 2; } if (f is AutoDoorsFeature) { return 0; } if (f is AutoRunFeature) { return 1; } if (f is SwimmingToolsFeature) { return 2; } if (f is MinimapClockFeature) { return 3; } if (f is FullFoodFeature) { return 4; } if (f is SpiritCollisionFeature) { return 5; } if (f is OrderedSummonsFeature) { return 6; } if (f is BuildSearchFixFeature) { return 7; } return 8; } public void Update() { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) input.Update(); shield.SetActive(input.Blocking); Player localPlayer = Player.m_localPlayer; if (open && (!Object.op_Implicit((Object)(object)localPlayer) || (Object)(object)localPlayer != (Object)(object)menuPlayer || ((Character)localPlayer).IsDead())) { Close(); } else { if (capturing) { return; } if (open && input.KeyDown((KeyCode)27)) { Close(); } else if (input.KeyDown(hotkey.Value)) { if (open) { Close(); } else if (Object.op_Implicit((Object)(object)localPlayer) && !((Character)localPlayer).IsDead() && !Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsVisible() && !InventoryGui.IsVisible() && !StoreGui.IsVisible() && !Minimap.IsOpen() && (!Object.op_Implicit((Object)(object)Chat.instance) || !Chat.instance.HasFocus())) { open = true; menuPlayer = localPlayer; float num = Math.Min(1080, Screen.width - 24); float num2 = Math.Min(860, Screen.height - 24); window = new Rect(((float)Screen.width - num) / 2f, ((float)Screen.height - num2) / 2f, num, num2); input.SetOpen(value: true, hotkey.Value); shield.SetActive(value: true); } } } } private void Close() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) open = false; capturing = false; input.SetOpen(value: false, hotkey.Value); } private void Save() { string text = save(); status = (text.StartsWith("Saved.") ? "Changes saved" : text); } public void Draw() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 //IL_0027: 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_0036: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (!open) { return; } EnsureStyles(); Event current = Event.current; if (capturing && (int)current.type == 4 && (int)current.keyCode != 0) { if ((int)current.keyCode == 27) { capturing = false; status = "Key change cancelled"; } else if (ZInput.IsKeyCodeValid(current.keyCode)) { hotkey.Value = current.keyCode; capturing = false; Save(); } current.Use(); } Fill(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), new Color(0f, 0f, 0f, 0.55f)); ((Rect)(ref window)).width = Math.Min(1080, Screen.width - 24); ((Rect)(ref window)).height = Math.Min(860, Screen.height - 24); ((Rect)(ref window)).x = Mathf.Clamp(((Rect)(ref window)).x, 0f, Math.Max(0f, (float)Screen.width - ((Rect)(ref window)).width)); ((Rect)(ref window)).y = Mathf.Clamp(((Rect)(ref window)).y, 0f, Math.Max(0f, (float)Screen.height - ((Rect)(ref window)).height)); window = GUI.Window(194732, window, new WindowFunction(DrawWindow), GUIContent.none, windowStyle); } private void DrawWindow(int id) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0155: 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_017b: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_0491: Unknown result type (might be due to invalid IL or missing references) //IL_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_04de: Unknown result type (might be due to invalid IL or missing references) //IL_04e9: Unknown result type (might be due to invalid IL or missing references) //IL_051a: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0566: Unknown result type (might be due to invalid IL or missing references) //IL_056b: Unknown result type (might be due to invalid IL or missing references) //IL_0587: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05ce: Unknown result type (might be due to invalid IL or missing references) //IL_05ed: Unknown result type (might be due to invalid IL or missing references) //IL_0622: Unknown result type (might be due to invalid IL or missing references) //IL_058f: Unknown result type (might be due to invalid IL or missing references) float width = ((Rect)(ref window)).width; float height = ((Rect)(ref window)).height; GUI.DrawTexture(new Rect(0f, 0f, width, height), (Texture)(object)background); Frame(new Rect(1f, 1f, width - 2f, height - 2f), gold); Frame(new Rect(5f, 5f, width - 10f, height - 10f), new Color(gold.r, gold.g, gold.b, 0.25f)); Corner(12f, 12f, 1, 1); Corner(width - 12f, 12f, -1, 1); Corner(12f, height - 12f, 1, -1); Corner(width - 12f, height - 12f, -1, -1); Frame(new Rect(32f, 25f, 44f, 48f), gold); Fill(new Rect(43f, 36f, 22f, 3f), gold); Fill(new Rect(53f, 36f, 3f, 27f), gold); GUI.Label(new Rect(96f, 24f, width - 270f, 54f), "TOGGLE QOL", titleStyle); GUI.Label(new Rect(width - 142f, 34f, 66f, 32f), ((object)hotkey.Value).ToString(), buttonStyle); if (GUI.Button(new Rect(width - 62f, 30f, 36f, 38f), "×", buttonStyle)) { Close(); } Fill(new Rect(32f, 91f, width - 64f, 1f), new Color(gold.r, gold.g, gold.b, 0.55f)); Rect val = default(Rect); ((Rect)(ref val))..ctor(28f, 104f, width - 56f, Math.Max(80f, height - 225f)); float num = ((Rect)(ref val)).width - 20f; float num2 = 0f; for (int i = 0; i < 4; i++) { num2 += 43f; foreach (QolFeature feature in features) { if (Category(feature) == i) { num2 += RowHeight(feature, num); } } num2 += 5f; } scroll = GUI.BeginScrollView(val, scroll, new Rect(0f, 0f, num, num2), false, false); float num3 = 0f; string[] array = new string[4] { "GENERAL", "HUD", "FOOD & SUMMONS", "FIXES" }; for (int j = 0; j < 4; j++) { GUI.Label(new Rect(4f, num3, num - 8f, 28f), array[j], headingStyle); Fill(new Rect(4f, num3 + 31f, num - 8f, 1f), new Color(0.42f, 0.44f, 0.41f, 0.6f)); num3 += 43f; foreach (QolFeature feature2 in features) { if (Category(feature2) == j) { float num4 = RowHeight(feature2, num); DrawRow(feature2, new Rect(0f, num3, num, num4)); num3 += num4; } } num3 += 5f; } GUI.EndScrollView(); float num5 = height - 107f; Fill(new Rect(32f, num5, width - 64f, 1f), new Color(gold.r, gold.g, gold.b, 0.5f)); GUI.Label(new Rect(34f, num5 + 17f, 125f, 34f), "Menu shortcut", labelStyle); GUI.Label(new Rect(160f, num5 + 17f, 85f, 34f), ((object)hotkey.Value).ToString(), buttonStyle); if (GUI.Button(new Rect(254f, num5 + 17f, 118f, 34f), capturing ? "Press key…" : "Change", buttonStyle)) { capturing = !capturing; } string text = (capturing ? "Press a key · Esc cancels" : status); Color contentColor = GUI.contentColor; GUI.contentColor = ((status == "Changes saved" && !capturing) ? teal : Color.white); GUI.Label(new Rect(390f, num5 + 12f, Math.Max(100f, width - 426f), 57f), text, smallStyle); GUI.contentColor = contentColor; GUI.Label(new Rect(34f, height - 34f, width - 68f, 22f), "The world keeps running while this menu is open.", smallStyle); GUI.DragWindow(new Rect(85f, 8f, Math.Max(1f, width - 250f), 76f)); } private static int Category(QolFeature f) { if (f is MinimapClockFeature) { return 1; } if (f is FullFoodFeature || f is SpiritCollisionFeature || f is OrderedSummonsFeature) { return 2; } if (f is BuildSearchFixFeature) { return 3; } return 0; } private static string Name(QolFeature f) { if (f is CrossbowReloadFeature) { return "Mobile crossbow reload"; } if (f is AutoDoorsFeature) { return "Auto doors"; } if (f is AutoRunFeature) { return "Auto-run steering"; } if (f is SwimmingToolsFeature) { return "Tools while swimming"; } if (f is MinimapClockFeature) { return "Day & time"; } if (f is FullFoodFeature) { return "No food decay"; } if (f is SpiritCollisionFeature) { return "Friendly summon collision"; } if (f is OrderedSummonsFeature) { return "Ordered summons"; } if (f is BuildSearchFixFeature) { return "Build-menu search"; } return f.Title; } private static string Summary(QolFeature f) { if (f is CrossbowReloadFeature) { return "Reload while sprinting and jumping."; } if (f is AutoDoorsFeature) { return "Open nearby doors and close them behind you."; } if (f is AutoRunFeature) { return "Steer with the camera; jumping keeps auto-run active."; } if (f is SwimmingToolsFeature) { return "Build, chop and mine without leaving the water."; } if (f is MinimapClockFeature) { return "Day counter and clock in half-hour steps."; } if (f is FullFoodFeature) { return "Keep food bonuses at full strength until expiry."; } if (f is SpiritCollisionFeature) { return "Walk through friendly Spirit Caller summons."; } if (f is OrderedSummonsFeature) { return "Boar → Wolf → Bear → Moose"; } if (f is BuildSearchFixFeature) { return "Type freely without triggering the menu shortcut."; } return f.Description; } private float RowHeight(QolFeature f, float width) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown bool flag = width < 850f || f is MinimapClockFeature; float val = (flag ? (width - 122f) : (width - 424f)); float num = labelStyle.CalcHeight(new GUIContent(Summary(f)), Math.Max(80f, val)); float num2 = Math.Max(flag ? 70 : 50, num + (float)(flag ? 36 : 18)); if (!f.Available) { num2 += smallStyle.CalcHeight(new GUIContent(f.Status), Math.Max(80f, width - 20f)) + 8f; } return num2; } private void DrawRow(QolFeature feature, Rect row) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: 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_0376: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_019c: 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_01db: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Expected O, but got Unknown bool flag = ((Rect)(ref row)).width < 850f || feature is MinimapClockFeature; if (((Rect)(ref row)).Contains(Event.current.mousePosition)) { Fill(row, new Color(1f, 1f, 1f, 0.025f)); } float num = ((Rect)(ref row)).width - 100f; MinimapClockFeature minimapClockFeature = feature as MinimapClockFeature; GUI.Label(new Rect(4f, ((Rect)(ref row)).y + 2f, (minimapClockFeature != null) ? (((Rect)(ref row)).width - 300f) : (flag ? (num - 10f) : 295f), 30f), new GUIContent(Name(feature), feature.Description), nameStyle); GUI.Label(new Rect((float)(flag ? 4 : 308), ((Rect)(ref row)).y + (float)(flag ? 33 : 5), flag ? (num - 14f) : (num - 320f), ((Rect)(ref row)).height - (float)(flag ? 36 : 8)), Summary(feature), labelStyle); bool enabled = GUI.enabled; GUI.enabled = enabled && feature.Available; Rect val = default(Rect); ((Rect)(ref val))..ctor(num, ((Rect)(ref row)).y + 5f, 96f, 30f); Color color = (feature.Enabled ? new Color(0.16f, 0.44f, 0.45f) : new Color(0.22f, 0.26f, 0.28f)); TintTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y + 1f, 56f, 28f), pill, color); TintTexture(new Rect(((Rect)(ref val)).x + (float)(feature.Enabled ? 30 : 3), ((Rect)(ref val)).y + 4f, 22f, 22f), knob, (Color)(feature.Available ? new Color(0.91f, 0.95f, 0.93f) : muted)); Color contentColor = GUI.contentColor; GUI.contentColor = (feature.Enabled ? teal : muted); GUI.Label(new Rect(((Rect)(ref val)).x + 63f, ((Rect)(ref val)).y, 35f, 30f), feature.Enabled ? "ON" : "OFF", stateStyle); GUI.contentColor = contentColor; if (GUI.Button(val, new GUIContent("", "Toggle " + Name(feature)), GUIStyle.none)) { try { feature.SetEnabled(!feature.Enabled); Save(); } catch (Exception ex) { feature.Fail(ex); status = "Could not change feature: " + ex.Message; } } if (minimapClockFeature != null) { float num2 = num - 166f; FormatButton(minimapClockFeature, new Rect(num2, ((Rect)(ref row)).y + 3f, 70f, 32f), amPm: false, "24h"); FormatButton(minimapClockFeature, new Rect(num2 + 70f, ((Rect)(ref row)).y + 3f, 83f, 32f), amPm: true, "AM/PM"); } GUI.enabled = enabled; if (!feature.Available) { GUI.Label(new Rect(4f, ((Rect)(ref row)).yMax - 36f, ((Rect)(ref row)).width - 8f, 36f), feature.Status, smallStyle); } Fill(new Rect(4f, ((Rect)(ref row)).yMax - 2f, ((Rect)(ref row)).width - 8f, 1f), new Color(1f, 1f, 1f, 0.035f)); } private void FormatButton(MinimapClockFeature clock, Rect rect, bool amPm, string text) { //IL_000a: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0076: 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) bool flag = clock.UseAmPm == amPm; Color backgroundColor = GUI.backgroundColor; if (flag) { GUI.backgroundColor = new Color(0.45f, 0.95f, 0.95f); } if (GUI.Button(rect, text, buttonStyle) && !flag) { try { clock.ToggleFormat(); Save(); } catch (Exception ex) { clock.Fail(ex); status = "Could not change clock: " + ex.Message; } } GUI.backgroundColor = backgroundColor; if (flag) { Frame(rect, new Color(0.33f, 0.66f, 0.66f)); } } private static void Fill(Rect rect, Color color) { //IL_0000: 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) TintTexture(rect, Texture2D.whiteTexture, color); } private static void TintTexture(Rect rect, Texture2D texture, Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) Color color2 = GUI.color; GUI.color = color; GUI.DrawTexture(rect, (Texture)(object)texture); GUI.color = color2; } private static void Frame(Rect r, Color c) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_006a: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) Fill(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, 1f), c); Fill(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).yMax - 1f, ((Rect)(ref r)).width, 1f), c); Fill(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, 1f, ((Rect)(ref r)).height), c); Fill(new Rect(((Rect)(ref r)).xMax - 1f, ((Rect)(ref r)).y, 1f, ((Rect)(ref r)).height), c); } private void Corner(float x, float y, int dx, int dy) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0049: 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_008c: Unknown result type (might be due to invalid IL or missing references) Fill(new Rect((dx > 0) ? x : (x - 22f), y, 22f, 1f), gold); Fill(new Rect(x, (dy > 0) ? y : (y - 22f), 1f, 22f), gold); Frame(new Rect((dx > 0) ? (x + 4f) : (x - 12f), (dy > 0) ? (y + 4f) : (y - 12f), 8f, 8f), gold); } private Texture2D Solid(Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_000b: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, color); val.Apply(); return val; } private Texture2D Rounded(int width, int height) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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) Texture2D val = new Texture2D(width, height, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; float num = (float)height / 2f - 1f; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { float num2 = Mathf.Clamp((float)j + 0.5f, num + 1f, (float)width - num - 1f); float num3 = Vector2.Distance(new Vector2((float)j + 0.5f, (float)i + 0.5f), new Vector2(num2, (float)height / 2f)); val.SetPixel(j, i, new Color(1f, 1f, 1f, Mathf.Clamp01(num + 0.5f - num3))); } } val.Apply(); return val; } private GUIStyle Text(int size, Color color, FontStyle weight) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) GUIStyle val = new GUIStyle(GUI.skin.label); val.fontSize = size; val.fontStyle = weight; val.wordWrap = true; GUIStyle val2 = val; val2.normal.textColor = color; return val2; } private void EnsureStyles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_00c4: 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_0109: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Expected O, but got Unknown //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Expected O, but got Unknown //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_028d: 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) if (windowStyle != null) { return; } background = new Texture2D(128, 128); Random random = new Random(418); for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num = (float)random.NextDouble() * 0.018f; background.SetPixel(j, i, new Color(0.045f + num, 0.068f + num, 0.078f + num, 0.985f)); } } background.Apply(); pill = Rounded(112, 56); knob = Rounded(44, 44); buttonTexture = Solid(new Color(0.12f, 0.15f, 0.16f, 0.7f)); hoverTexture = Solid(new Color(0.2f, 0.28f, 0.29f, 0.9f)); selectedTexture = Solid(new Color(0.14f, 0.38f, 0.4f)); windowStyle = new GUIStyle(GUIStyle.none); titleStyle = Text(36, gold, (FontStyle)0); headingStyle = Text(16, gold, (FontStyle)1); nameStyle = Text(19, new Color(0.94f, 0.95f, 0.92f), (FontStyle)1); labelStyle = Text(16, new Color(0.78f, 0.81f, 0.8f), (FontStyle)0); smallStyle = Text(13, muted, (FontStyle)0); stateStyle = Text(13, Color.white, (FontStyle)1); stateStyle.alignment = (TextAnchor)3; GUIStyle val = new GUIStyle(GUI.skin.button); val.fontSize = 15; val.alignment = (TextAnchor)4; val.border = new RectOffset(0, 0, 0, 0); buttonStyle = val; buttonStyle.normal.background = buttonTexture; buttonStyle.normal.textColor = new Color(0.88f, 0.92f, 0.9f); buttonStyle.hover.background = hoverTexture; buttonStyle.hover.textColor = Color.white; buttonStyle.active.background = selectedTexture; buttonStyle.active.textColor = Color.white; } public void Dispose() { if (open) { Close(); } Texture2D[] array = (Texture2D[])(object)new Texture2D[6] { background, pill, knob, buttonTexture, hoverTexture, selectedTexture }; foreach (Texture2D val in array) { if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)val); } } shield.Dispose(); } } internal sealed class SpiritCollisionFeature : QolFeature { private sealed class Pair { public Collider A; public Collider B; public bool PreviouslyIgnored; } private sealed class Bodies { public Collider Root; public Rigidbody Body; public float RefreshAt; public readonly List<Collider> Colliders = new List<Collider>(); } private struct Node { public Character Character; public bool Spirit; } private static readonly HashSet<int> SpiritPrefabs = new HashSet<int> { StringExtensionMethods.GetStableHashCode("Boar_spiritcaller"), StringExtensionMethods.GetStableHashCode("Wolf_spiritcaller"), StringExtensionMethods.GetStableHashCode("Moose_spiritcaller"), StringExtensionMethods.GetStableHashCode("Bjorn_spiritcaller") }; private readonly Dictionary<ulong, Pair> pairs = new Dictionary<ulong, Pair>(); private readonly HashSet<ulong> seen = new HashSet<ulong>(); private readonly List<ulong> removedPairs = new List<ulong>(); private readonly Dictionary<Character, Bodies> bodyCache = new Dictionary<Character, Bodies>(); private readonly HashSet<Character> live = new HashSet<Character>(); private readonly List<Character> removedCharacters = new List<Character>(); private readonly List<Node> characters = new List<Node>(); public SpiritCollisionFeature(ConfigFile config) : base(config, "FriendlySpiritCollisions", "Friendly Spirit Caller collisions", "Anyone's four Spirit Caller summons pass through friendly characters. Every client and dedicated server must use matching settings; PvP-enabled players retain collision.") { } protected override void OnTick() { UpdatePairs(); } protected override void OnToggle(bool next) { if (!next) { Clear(); } } protected override void OnStop() { Clear(); } private void UpdatePairs() { seen.Clear(); live.Clear(); characters.Clear(); foreach (Character allCharacter in Character.GetAllCharacters()) { if (Object.op_Implicit((Object)(object)allCharacter) && ((Component)allCharacter).gameObject.activeInHierarchy && !allCharacter.IsDead()) { ZNetView component = ((Component)allCharacter).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid()) { live.Add(allCharacter); characters.Add(new Node { Character = allCharacter, Spirit = SpiritPrefabs.Contains(component.GetZDO().GetPrefab()) }); } } } for (int i = 0; i < characters.Count; i++) { Node node = characters[i]; if (!node.Spirit) { continue; } for (int j = 0; j < characters.Count; j++) { Node node2 = characters[j]; if (i == j || (node2.Spirit && j < i) || !Friendly(node.Character, node2.Character)) { continue; } List<Collider> bodies = GetBodies(node.Character); List<Collider> bodies2 = GetBodies(node2.Character); foreach (Collider item in bodies) { foreach (Collider item2 in bodies2) { if (ActiveBody(item, node.Character) && ActiveBody(item2, node2.Character) && (Object)(object)item != (Object)(object)item2) { AddPair(item, item2); } } } } } removedPairs.Clear(); foreach (KeyValuePair<ulong, Pair> pair in pairs) { if (!seen.Contains(pair.Key)) { removedPairs.Add(pair.Key); } } foreach (ulong removedPair in removedPairs) { Restore(pairs[removedPair]); pairs.Remove(removedPair); } removedCharacters.Clear(); foreach (KeyValuePair<Character, Bodies> item3 in bodyCache) { if (!live.Contains(item3.Key)) { removedCharacters.Add(item3.Key); } } foreach (Character removedCharacter in removedCharacters) { bodyCache.Remove(removedCharacter); } } private static bool Friendly(Character a, Character b) { if ((a.IsPlayer() && a.IsPVPEnabled()) || (b.IsPlayer() && b.IsPVPEnabled())) { return false; } if (!BaseAI.IsEnemy(a, b)) { return !BaseAI.IsEnemy(b, a); } return false; } private List<Collider> GetBodies(Character character) { if (!bodyCache.TryGetValue(character, out var value)) { value = new Bodies(); bodyCache.Add(character, value); } Collider collider = (Collider)(object)character.GetCollider(); Rigidbody val = (Object.op_Implicit((Object)(object)collider) ? collider.attachedRigidbody : null); if ((Object)(object)value.Root != (Object)(object)collider || (Object)(object)value.Body != (Object)(object)val || Time.time >= value.RefreshAt) { value.Root = collider; value.Body = val; value.RefreshAt = Time.time + 0.5f; value.Colliders.Clear(); if (Object.op_Implicit((Object)(object)collider)) { value.Colliders.Add(collider); } if (Object.op_Implicit((Object)(object)val)) { Collider[] componentsInChildren = ((Component)character).GetComponentsInChildren<Collider>(true); foreach (Collider val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)(object)collider && (Object)(object)val2.attachedRigidbody == (Object)(object)val && (Object)(object)((Component)val2).GetComponentInParent<Character>() == (Object)(object)character) { value.Colliders.Add(val2); } } } } return value.Colliders; } private static bool ActiveBody(Collider collider, Character character) { if (!Object.op_Implicit((Object)(object)collider) || !collider.enabled || !((Component)collider).gameObject.activeInHierarchy || collider.isTrigger) { return false; } Collider collider2 = (Collider)(object)character.GetCollider(); if ((Object)(object)collider == (Object)(object)collider2) { return true; } if (Object.op_Implicit((Object)(object)collider2) && Object.op_Implicit((Object)(object)collider2.attachedRigidbody) && (Object)(object)collider.attachedRigidbody == (Object)(object)collider2.attachedRigidbody) { return (Object)(object)((Component)collider).GetComponentInParent<Character>() == (Object)(object)character; } return false; } private void AddPair(Collider a, Collider b) { int num = ((Object)a).GetInstanceID(); int num2 = ((Object)b).GetInstanceID(); if (num > num2) { Collider val = a; a = b; b = val; int num3 = num; num = num2; num2 = num3; } ulong num4 = ((ulong)(uint)num << 32) | (uint)num2; seen.Add(num4); if (pairs.TryGetValue(num4, out var value) && ((Object)(object)value.A != (Object)(object)a || (Object)(object)value.B != (Object)(object)b)) { Restore(value); pairs.Remove(num4); } if (!pairs.TryGetValue(num4, out value)) { Pair pair = new Pair(); pair.A = a; pair.B = b; pair.PreviouslyIgnored = Physics.GetIgnoreCollision(a, b); value = pair; pairs.Add(num4, value); } if (!Physics.GetIgnoreCollision(a, b)) { Physics.IgnoreCollision(a, b, true); } } private static void Restore(Pair pair) { if (Object.op_Implicit((Object)(object)pair.A) && Object.op_Implicit((Object)(object)pair.B) && !pair.PreviouslyIgnored) { Physics.IgnoreCollision(pair.A, pair.B, false); } } private void Clear() { foreach (Pair value in pairs.Values) { Restore(value); } pairs.Clear(); bodyCache.Clear(); seen.Clear(); live.Clear(); characters.Clear(); } } internal sealed class SummonCycleState { public static readonly string[] PrefabOrder = new string[4] { "Boar_spiritcaller", "Wolf_spiritcaller", "Bjorn_spiritcaller", "Moose_spiritcaller" }; public int NextIndex { get; private set; } public SummonCycleState(int savedIndex) { NextIndex = ((savedIndex >= 0 && savedIndex < 4) ? savedIndex : 0); } public bool Commit(int createdIndex) { if (createdIndex != NextIndex) { return false; } NextIndex = (NextIndex + 1) % 4; return true; } } internal sealed class SwimmingToolsFeature : QolFeature { private static SwimmingToolsFeature instance; private Harmony harmony; private static FieldInfo hiddenRight; private static FieldInfo hiddenLeft; private static FieldInfo rightItem; private static FieldInfo leftItem; public SwimmingToolsFeature(ConfigFile config) : base(config, "SwimmingTools", "Use tools while swimming", "Build, repair, chop and mine while swimming with hammers, hoes, cultivators, axes and pickaxes. Other weapons stay restricted; normal costs and swim stamina apply.") { } public override void Initialize() { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown instance = this; hiddenRight = AccessTools.Field(typeof(Humanoid), "m_hiddenRightItem"); hiddenLeft = AccessTools.Field(typeof(Humanoid), "m_hiddenLeftItem"); rightItem = AccessTools.Field(typeof(Humanoid), "m_rightItem"); leftItem = AccessTools.Field(typeof(Humanoid), "m_leftItem"); if (hiddenRight == null || hiddenLeft == null || rightItem == null || leftItem == null) { throw new MissingMemberException("Hidden equipment fields changed."); } harmony = new Harmony("benowy.qol.swimmingtools"); Patch(typeof(Humanoid), "EquipItem", "EquipCheck"); Patch(typeof(Humanoid), "UpdateEquipment", "EquipmentCheck"); Patch(typeof(Player), "Update", "RestoreCheck"); } private void Patch(Type type, string name, string patch) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(type, name, (Type[])null, (Type[])null); if (methodInfo == null) { throw new MissingMethodException(type.Name, name); } harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(SwimmingToolsFeature), patch, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); } private static bool Active(Character character) { if (instance != null && instance.Running && instance.Enabled && Object.op_Implicit((Object)(object)character)) { return (Object)(object)character == (Object)(object)Player.m_localPlayer; } return false; } private static bool Allowed(ItemData item) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 if (item == null || item.m_shared == null) { return false; } if (!Object.op_Implicit((Object)(object)item.m_shared.m_buildPieces) && (int)item.m_shared.m_skillType != 7) { return (int)item.m_shared.m_skillType == 12; } return true; } private static bool HandsAllowed(Humanoid human, bool hidden) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown ItemData val = (hidden ? ((ItemData)hiddenRight.GetValue(human)) : ((ItemData)rightItem.GetValue(human))); ItemData val2 = (hidden ? ((ItemData)hiddenLeft.GetValue(human)) : ((ItemData)leftItem.GetValue(human))); if ((val != null || val2 != null) && (val == null || Allowed(val))) { if (val2 != null) { return Allowed(val2); } return true; } return false; } private static bool EquipSwimming(Character character, ItemData item) { if (character.IsSwimming()) { if (Active(character)) { return !Allowed(item); } return true; } return false; } private static bool EquipmentSwimming(Character character) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but