using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("SoDQuickRest")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.11.1.0")] [assembly: AssemblyInformationalVersion("0.11.1")] [assembly: AssemblyProduct("SoDQuickRest")] [assembly: AssemblyTitle("SoDQuickRest")] [assembly: AssemblyVersion("0.11.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SoDQuickRest { [BepInPlugin("sm3gm.sod.skiptimeanywhere", "Skip Time Anywhere", "1.0.0")] public sealed class Plugin : BasePlugin { public const string VER = "1.0.0"; internal static ManualLogSource L; internal static ConfigEntry Speed; internal static ConfigEntry SkipSpeed; internal static ConfigEntry BoostGameRest; internal static ConfigEntry WatchKey; internal static ConfigEntry FullSkipKey; internal static ConfigEntry EarlierKey; internal static ConfigEntry LaterKey; internal static ConfigEntry WakeOnPhone; internal static ConfigEntry WakeOnKnock; internal static ConfigEntry WakeOnMurder; internal static ConfigEntry WakeOnBodyFound; internal static ConfigEntry WakeWhenColder; internal static ConfigEntry WakeWhenHurt; internal static ConfigEntry ShowWatchHint; internal static ConfigEntry StandingMenu; internal static ConfigEntry StandingMenuDelay; internal static ConfigEntry ReplaceHoursToggle; internal static ConfigEntry PadAlarm; internal static ConfigEntry PadHour; internal static ConfigEntry PromptAlarmSlot; internal static ConfigEntry PromptHourSlot; public override void Load() { //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Expected O, but got Unknown L = ((BasePlugin)this).Log; Speed = ((BasePlugin)this).Config.Bind("Speed", "RestSpeed", 80f, "How many times faster than normal the clock runs while you wait or sleep. The game's own speed is 40."); SkipSpeed = ((BasePlugin)this).Config.Bind("Speed", "SkipSpeed", 2000f, "Speed for Ctrl+Shift+Alt+R, the near-instant skip. The world still runs, just very fast, so wake-ups still work."); BoostGameRest = ((BasePlugin)this).Config.Bind("Speed", "BoostGameRest", true, "Also speed up the game's own sleeping and waiting in beds and chairs. Turn off if another mod already changes that."); WatchKey = ((BasePlugin)this).Config.Bind("Keys", "SkipHourKey", "T", "With the watch held up, or while sitting or lying down to pass time: skip one hour. Unity key name, empty = off."); FullSkipKey = ((BasePlugin)this).Config.Bind("Keys", "SkipToWatchTimeKey", "Y", "Skip straight to the time set on the watch. Unity key name, empty = off."); EarlierKey = ((BasePlugin)this).Config.Bind("Keys", "WatchEarlierKey", "Comma", "With the watch held up: set the watch time 15 minutes earlier. Unity key name."); LaterKey = ((BasePlugin)this).Config.Bind("Keys", "WatchLaterKey", "Period", "With the watch held up: set the watch time 15 minutes later. Unity key name."); WakeOnPhone = ((BasePlugin)this).Config.Bind("Wake", "PhoneRings", true, "Wake when a phone rings where you are."); WakeOnKnock = ((BasePlugin)this).Config.Bind("Wake", "DoorKnock", true, "Wake when someone knocks on a door near you."); WakeOnMurder = ((BasePlugin)this).Config.Bind("Wake", "Murder", true, "Wake when a murder happens."); WakeOnBodyFound = ((BasePlugin)this).Config.Bind("Wake", "BodyFound", true, "Wake when a body is found."); PromptAlarmSlot = ((BasePlugin)this).Config.Bind("Prompts", "AlarmPromptButton", "crouch", "Game button slot for the Skip To Alarm prompt while time passes (game names such as flashlight, crouch, alternative). The prompt shows the real key or controller button. Empty = the alarm menu's own button."); PromptHourSlot = ((BasePlugin)this).Config.Bind("Prompts", "HourPromptButton", "", "Game button slot for the Skip One Hour prompt while time passes. Empty = the alarm menu's own button."); PadAlarm = ((BasePlugin)this).Config.Bind("Controller", "SkipToAlarmPadButton", "JoystickButton1", "Controller button that skips to the alarm while time passes (JoystickButton1 = B on an Xbox pad, the button the prompt shows). Empty = off."); PadHour = ((BasePlugin)this).Config.Bind("Controller", "SkipHourButton", "", "Controller button that skips one hour while time passes (JoystickButton2 = X on an Xbox pad). Empty = off."); ReplaceHoursToggle = ((BasePlugin)this).Config.Bind("Watch", "SkipToAlarmPrompt", true, "In the pass-time menu (standing, chairs, beds), the Switch Hours/Minutes prompt becomes Skip To Alarm. Alarm Forward/Back still step the alarm."); StandingMenu = ((BasePlugin)this).Config.Bind("Watch", "StandingMenu", true, "Look at your watch and hold still to get the game's own pass-time menu while standing."); StandingMenuDelay = ((BasePlugin)this).Config.Bind("Watch", "StandingMenuDelay", 1.5f, "Seconds of holding still with the watch raised before the menu opens."); ShowWatchHint = ((BasePlugin)this).Config.Bind("Keys", "ShowWatchHint", true, "Show the pass time keys each time you raise the watch."); WakeWhenColder = ((BasePlugin)this).Config.Bind("Wake", "ColdBelow", 0.15f, "Wake when your warmth drops to this or lower (0 = freezing, 1 = warm) and is still dropping, so you do not freeze to death outside. Warming up somewhere warm never wakes you. 0 = off."); WakeWhenHurt = ((BasePlugin)this).Config.Bind("Wake", "HealthBelow", 0.5f, "Wake when your health drops to this share of the maximum or lower. 0 = off."); Harmony val = new Harmony("sm3gm.sod.skiptimeanywhere"); val.PatchAll(typeof(PromptText)); val.PatchAll(typeof(Patches)); val.PatchAll(typeof(StandMenuPatches)); val.PatchAll(typeof(SkipPromptPatches)); val.PatchAll(typeof(SkipButtonPatches)); ((BasePlugin)this).AddComponent(); ManualLogSource l = L; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Skip Time Anywhere "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted("1.0.0"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" loaded"); } l.LogInfo(val2); } } internal static class Rest { internal static Interactable? Spot; internal static bool Own; internal static float HoursLeft; internal static float OwnSpeed; internal static float LastClock = -1f; private static float lastSkipPress = -1f; internal static bool GameResting { get { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 try { return (Object)(object)Player.Instance != (Object)null && Player.Instance.spendingTimeMode && (int)SessionData.Instance.currentTimeSpeed == 3; } catch { return false; } } } internal static bool Resting { get { if (!Own) { return GameResting; } return true; } } internal static float Clock => SessionData.Instance.decimalClock; internal static void StartOrExtend(bool skip) { if (!Own) { Own = true; HoursLeft = 0f; LastClock = Clock; try { SessionData.Instance.SetTimeSpeed((TimeSpeed)3); } catch { } } HoursLeft = Math.Min(HoursLeft + 1f, 24f); OwnSpeed = (skip ? Plugin.SkipSpeed.Value : Plugin.Speed.Value); Note((skip ? "Skipping" : "Waiting") + " until " + Fmt(Clock + HoursLeft) + ". Press again for another hour, Esc or move to stop."); } internal static float AlarmHoursAhead() { try { float alarm = Player.Instance.alarm; float clock = Clock; if (alarm <= 0f) { return -1f; } float num = alarm % 24f - clock; if (num < 0f) { num += 24f; } return num; } catch { return -1f; } } internal static void Skip(float hours, string what) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown if (!Own) { Own = true; LastClock = Clock; try { SessionData.Instance.SetTimeSpeed((TimeSpeed)3); } catch { } HoursLeft = 0f; } HoursLeft = Math.Min(HoursLeft + hours, 24f); OwnSpeed = Plugin.SkipSpeed.Value; ManualLogSource l = Plugin.L; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(25, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[REST] skip "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(hours, "0.00"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" h ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(what); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("), until "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Fmt(Clock + HoursLeft)); } l.LogInfo(val); Note("Skipping to " + Fmt(Clock + HoursLeft) + "."); } internal static void StopOwn(string why) { if (Own) { Own = false; try { SessionData.Instance.SetTimeSpeed((TimeSpeed)1); } catch { } if (why.Length > 0) { Note(why); } } } internal static void Wake(string why) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Invalid comparison between Unknown and I4 if (!Resting) { return; } ManualLogSource l = Plugin.L; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(15, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[REST] waking: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(why); } l.LogInfo(val); bool own = Own; if (own) { StopOwn(""); } try { if (Spot != null && Player.Instance.spendingTimeMode) { ActionController.Instance.CancelPassTime(Spot, Spot.node, (Actor)(object)Player.Instance); } if ((int)SessionData.Instance.currentTimeSpeed != 1) { SessionData.Instance.SetTimeSpeed((TimeSpeed)1); } } catch (Exception ex) { Plugin.L.LogWarning((object)("[REST] wake failed: " + ex.Message)); } if (StandMenu.Active) { StandMenu.Close(); } Note((own ? "You stopped waiting: " : "You woke up: ") + why); } internal static string Fmt(float h) { h %= 24f; int num = (int)h; int value = (int)((h - (float)num) * 60f); return $"{num:00}:{value:00}"; } internal static bool Debounce() { if (Time.unscaledTime - lastSkipPress < 0.3f) { return false; } lastSkipPress = Time.unscaledTime; return true; } internal static void Note(string msg) { //IL_000d: 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) try { InterfaceController.Instance.NewGameMessage((GameMessageType)0, 0, msg, (Icon)3, (AudioEvent)null, false, default(Color), -1, 0f, (RectTransform)null, (PingOnComplete)0, (Evidence)null, (List)null, (Sprite)null); } catch { } } } [HarmonyPatch] internal static class Patches { [HarmonyPatch(typeof(ActionController), "PassTime")] [HarmonyPrefix] private static void PassTime(Interactable what) { Rest.Spot = what; } [HarmonyPatch(typeof(SessionData), "SetTimeSpeed")] [HarmonyPostfix] private static void SpeedSet() { Keeper.Apply(); } [HarmonyPatch(typeof(TelephoneController), "AddActiveCall")] [HarmonyPostfix] private static void Call(PhoneCall newCall) { if (!Plugin.WakeOnPhone.Value || !Rest.Resting) { return; } try { NewGameLocation currentGameLocation = ((Actor)Player.Instance).currentGameLocation; if (((newCall != null) ? newCall.toNS : null) != null && (Object)(object)currentGameLocation != (Object)null && (Object)(object)newCall.toNS.location == (Object)(object)currentGameLocation) { Rest.Wake("the phone is ringing"); } } catch { } } [HarmonyPatch(typeof(NewDoor), "OnKnock")] [HarmonyPostfix] private static void Knock(NewDoor __instance) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.WakeOnKnock.Value || !Rest.Resting) { return; } try { if (Vector3.Distance(((Component)__instance).transform.position, ((Component)Player.Instance).transform.position) < 15f) { Rest.Wake("someone is knocking"); } } catch { } } [HarmonyPatch(typeof(MurderController), "OnVictimKilled")] [HarmonyPostfix] private static void Killed() { if (Plugin.WakeOnMurder.Value) { Rest.Wake("there has been a murder"); } } [HarmonyPatch(typeof(MurderController), "OnVictimDiscovery")] [HarmonyPostfix] private static void Found() { if (Plugin.WakeOnBodyFound.Value) { Rest.Wake("a body has been found"); } } } public class Keeper : MonoBehaviour { private static KeyCode? hourKey; private static KeyCode? fullKey; private static KeyCode? earlier; private static KeyCode? later; private static KeyCode? padAlarm; private static KeyCode? padHour; private static bool wasRunning; private static bool watchShown; private float nextBody; private float lastHeat = -1f; private float lowestHeat = 2f; public Keeper(IntPtr ptr) : base(ptr) { } internal static void Apply() { try { float num = (Rest.Own ? Rest.OwnSpeed : ((Plugin.BoostGameRest.Value && Rest.GameResting) ? Plugin.Speed.Value : 0f)); if (num > 0f && SessionData.Instance.currentTimeMultiplier < num) { SessionData.Instance.currentTimeMultiplier = num; } } catch { } } private static string Or(string text, string pad) { if (!string.IsNullOrWhiteSpace(pad)) { return text + " or " + PadName(pad); } return text; } private static string PadName(string key) { return key switch { "JoystickButton0" => "A", "JoystickButton1" => "B", "JoystickButton2" => "X", "JoystickButton3" => "Y", "JoystickButton4" => "LB", "JoystickButton5" => "RB", "JoystickButton6" => "Back", "JoystickButton7" => "Start", "JoystickButton8" => "left stick", "JoystickButton9" => "right stick", _ => key, }; } private static bool KeyDown(ref KeyCode? cache, ConfigEntry entry) { //IL_004f: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (!cache.HasValue) { string text = entry.Value?.Trim() ?? ""; cache = (KeyCode)((text.Length > 0 && Enum.TryParse(text, ignoreCase: true, out KeyCode result)) ? ((int)result) : 0); } if (cache != (KeyCode?)0) { return Input.GetKeyDown(cache.Value); } return false; } private static string Pretty(string key) { if (!(key == "Comma")) { if (key == "Period") { return "."; } return key; } return ","; } private static bool HoldingWatch() { try { FirstPersonItemController instance = FirstPersonItemController.Instance; object obj; if (instance == null) { obj = null; } else { FirstPersonItem currentItem = instance.currentItem; obj = ((currentItem != null) ? ((Object)currentItem).name : null); } if (obj == null) { obj = ""; } return ((string)obj).IndexOf("watch", StringComparison.OrdinalIgnoreCase) >= 0; } catch { return false; } } private void Update() { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Expected O, but got Unknown //IL_04f6: Unknown result type (might be due to invalid IL or missing references) //IL_04fc: Invalid comparison between Unknown and I4 bool flag = Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305); bool flag2 = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); bool skip = Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307); try { bool flag3 = HoldingWatch(); StandMenu.Tick(flag3); if (flag3 && !watchShown && Plugin.ShowWatchHint.Value) { Rest.Note("Hold still to pass time."); } watchShown = flag3; bool flag4 = false; try { flag4 = (Object)(object)Player.Instance != (Object)null && (Player.Instance.spendingTimeMode || Player.Instance.setAlarmMode); } catch { } bool flag5 = default(bool); if (flag3 && !flag && (KeyDown(ref earlier, Plugin.EarlierKey) || KeyDown(ref later, Plugin.LaterKey))) { Player instance = Player.Instance; bool keyDown = Input.GetKeyDown(later.GetValueOrDefault()); if (!instance.setAlarmMode) { instance.SetSettingAlarmMode(true); if (Rest.AlarmHoursAhead() < 0.25f) { instance.alarm = Rest.Clock; } } instance.AddToAlarmTime(keyDown ? 0.25f : (-0.25f)); ManualLogSource l = Plugin.L; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(36, 2, ref flag5); if (flag5) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[REST] watch set to "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(instance.alarm, "0.00"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (setAlarmMode="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(instance.setAlarmMode); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } l.LogInfo(val); Rest.Note($"Watch set to {Rest.Fmt(instance.alarm)}. {Plugin.FullSkipKey.Value} to skip there, {Plugin.WatchKey.Value} for one hour."); } if ((flag3 || flag4) && !flag && KeyDown(ref hourKey, Plugin.WatchKey)) { Rest.LastClock = Rest.Clock; Rest.Skip(1f, "one hour"); } if ((flag3 || flag4) && !flag && KeyDown(ref fullKey, Plugin.FullSkipKey)) { float num = Rest.AlarmHoursAhead(); if (num <= 0.01f) { Rest.Note("Set a time on the watch first."); } else { Rest.LastClock = Rest.Clock; Rest.Skip(num, "the watch time"); } } bool flag6 = false; try { flag6 = (Object)(object)Player.Instance != (Object)null && Player.Instance.spendingTimeMode && !Player.Instance.setAlarmMode; } catch { } if (flag6 && !wasRunning && Plugin.ShowWatchHint.Value) { Rest.Note(Or("Skip to alarm: R", Plugin.PadAlarm.Value) + ". " + Or("One hour: " + Plugin.WatchKey.Value, Plugin.PadHour.Value) + "."); } wasRunning = flag6; if (flag6 && KeyDown(ref padHour, Plugin.PadHour) && Rest.Debounce()) { Rest.LastClock = Rest.Clock; Rest.Skip(1f, "one hour"); } if (!flag && Plugin.ReplaceHoursToggle.Value && (Input.GetKeyDown((KeyCode)114) || (flag6 && KeyDown(ref padAlarm, Plugin.PadAlarm))) && Rest.Debounce() && flag6) { float num2 = Rest.AlarmHoursAhead(); ManualLogSource l2 = Plugin.L; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(52, 1, ref flag5); if (flag5) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[REST] Skip To Alarm pressed while resting, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num2, "0.00"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" h ahead"); } l2.LogInfo(val); if (num2 <= 0.01f) { Rest.Note("Set the alarm on your watch first."); } else { Rest.LastClock = Rest.Clock; Rest.Skip(num2, "the alarm"); } } if (flag && flag2 && Input.GetKeyDown((KeyCode)114) && (Object)(object)SessionData.Instance != (Object)null && (Object)(object)Player.Instance != (Object)null) { if (!Rest.Own) { Rest.LastClock = Rest.Clock; } Rest.StartOrExtend(skip); } if (Rest.Own) { if (Input.GetKeyDown((KeyCode)27) || Input.GetKeyDown((KeyCode)119) || Input.GetKeyDown((KeyCode)97) || Input.GetKeyDown((KeyCode)115) || Input.GetKeyDown((KeyCode)100)) { Rest.StopOwn("You stopped waiting."); } else { float clock = Rest.Clock; Rest.HoursLeft -= ((clock >= Rest.LastClock) ? (clock - Rest.LastClock) : (clock + 24f - Rest.LastClock)); Rest.LastClock = clock; if (Rest.HoursLeft <= 0f) { Rest.StopOwn("Done waiting."); } else if ((int)SessionData.Instance.currentTimeSpeed != 3) { SessionData.Instance.SetTimeSpeed((TimeSpeed)3); } } } } catch { } BodyCheck(); Apply(); } private void BodyCheck() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown if (!Rest.Resting) { if (lowestHeat < 2f) { ManualLogSource l = Plugin.L; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(59, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[REST] rest over: lowest warmth "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(lowestHeat, "0.00"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (wakes at "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Plugin.WakeWhenColder.Value, "0.00"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" while dropping)"); } l.LogInfo(val); } lowestHeat = 2f; lastHeat = -1f; } else { if (Time.unscaledTime < nextBody) { return; } nextBody = Time.unscaledTime + 0.25f; try { Player instance = Player.Instance; float heat = ((Human)instance).heat; bool flag2 = lastHeat >= 0f && heat < lastHeat - 0.0001f; lastHeat = heat; if (heat < lowestHeat) { lowestHeat = heat; } if (Plugin.WakeWhenColder.Value > 0f && heat <= Plugin.WakeWhenColder.Value && flag2) { Rest.Wake("you are getting cold"); } else if (Plugin.WakeWhenHurt.Value > 0f && ((Actor)instance).maximumHealth > 0f && ((Actor)instance).currentHealth / ((Actor)instance).maximumHealth <= Plugin.WakeWhenHurt.Value) { Rest.Wake("you are hurt"); } } catch { } } } } internal static class StandMenu { internal static bool Active; private static float stillSince = -1f; private static Vector3 lastPos; internal static Interactable? Spot; private static GameObject? spotObject; private static Vector3 standPos; private static Quaternion standRot; internal static float HoldUntil; internal static float GuardUntil; private static Vector3 guardPos; private static bool loggedMove; private static InteractablePreset? chairPreset; internal static bool InGuard => Time.unscaledTime < GuardUntil; internal static void Tick(bool watch) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Expected O, but got Unknown //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Expected O, but got Unknown if (!Plugin.StandingMenu.Value) { return; } Player instance = Player.Instance; if ((Object)(object)instance == (Object)null) { return; } bool flag = default(bool); if (!Active && Time.unscaledTime < GuardUntil) { Vector3 position = ((Component)instance).transform.position; float num = Vector3.Distance(position, guardPos); if (num > 3f) { ManualLogSource l = Plugin.L; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(47, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[REST] moved "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num, "0.0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" m in one step after resting (to "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(position); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } l.LogInfo(val); } guardPos = position; } if (Time.unscaledTime < HoldUntil) { return; } if (Active) { Interactable lockedInInteraction = InteractionController.Instance.lockedInInteraction; bool num2 = lockedInInteraction != null && Spot != null && ((Il2CppObjectBase)lockedInInteraction).Pointer == ((Il2CppObjectBase)Spot).Pointer; bool flag2 = instance.spendingTimeMode && Spot != null && Rest.Spot != null && ((Il2CppObjectBase)Rest.Spot).Pointer == ((Il2CppObjectBase)Spot).Pointer; if (!num2 && !flag2) { ManualLogSource l2 = Plugin.L; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(60, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[REST] stand menu closed (now locked into '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted((lockedInInteraction == null) ? "nothing" : lockedInInteraction.GetName()); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("', passing time "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(instance.spendingTimeMode); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } l2.LogInfo(val); Active = false; Cleanup(); HoldUntil = Time.unscaledTime + 1f; StartGuard(); return; } float num3 = Vector3.Distance(((Component)instance).transform.position, standPos); if (num3 > 3f && !loggedMove) { loggedMove = true; ManualLogSource l3 = Plugin.L; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(44, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[REST] moved "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num3, "0.0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" m while the watch menu is open"); } l3.LogInfo(val); } return; } if (instance.spendingTimeMode && InteractionController.Instance.lockedInInteraction == null && !Rest.Own) { Plugin.L.LogInfo((object)"[REST] cleared a leftover pass-time state"); try { instance.SetSettingAlarmMode(false); } catch { } try { instance.spendingTimeMode = false; } catch { } } if (!watch || instance.spendingTimeMode || InteractionController.Instance.lockedInInteraction != null) { stillSince = -1f; return; } Vector3 position2 = ((Component)instance).transform.position; if (stillSince < 0f || Vector3.Distance(position2, lastPos) > 0.05f) { stillSince = Time.unscaledTime; lastPos = position2; } else if (!(Time.unscaledTime - stillSince < Plugin.StandingMenuDelay.Value)) { stillSince = -1f; Open(instance); } } private static void StartGuard() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) loggedMove = false; GuardUntil = Time.unscaledTime + 10f; guardPos = (((Object)(object)Player.Instance != (Object)null) ? ((Component)Player.Instance).transform.position : standPos); } private static void Open(Player p) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0081: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Expected O, but got Unknown //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) try { bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val; if (p.spendingTimeMode || p.setAlarmMode) { ManualLogSource l = Plugin.L; val = new BepInExInfoLogInterpolatedStringHandler(66, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[REST] stand menu: clearing leftover state (passing time "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(p.spendingTimeMode); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", alarm "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(p.setAlarmMode); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } l.LogInfo(val); try { p.SetSettingAlarmMode(false); } catch { } try { p.spendingTimeMode = false; } catch { } } standPos = ((Component)p).transform.position; standRot = ((Component)p).transform.rotation; InteractablePreset val2 = ChairPreset(); if ((SoCustomComparison)(object)val2 == (SoCustomComparison)null) { Plugin.L.LogInfo((object)"[REST] stand menu: no chair preset"); return; } spotObject = new GameObject("SkipTimeSpot"); spotObject.transform.position = ((Component)p).transform.position; spotObject.transform.rotation = ((Component)p).transform.rotation; Spot = InteractableCreator.Instance.CreateTransformInteractable(val2, spotObject.transform, (Human)null, (Evidence)null, Vector3.zero, Vector3.zero, (List)null); if (Spot == null) { Plugin.L.LogInfo((object)"[REST] stand menu: could not create the spot"); Cleanup(); return; } Active = true; InteractionController.Instance.SetLockedInInteractionMode(Spot, 0, false); ActionController.Instance.PassTime(Spot, Spot.node ?? ((Actor)p).currentNode, (Actor)(object)p); ManualLogSource l2 = Plugin.L; val = new BepInExInfoLogInterpolatedStringHandler(40, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[REST] stand menu open at your feet ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Vector3.Distance(Spot.wPos, ((Component)p).transform.position), "0.0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" m)"); } l2.LogInfo(val); } catch (Exception ex) { Active = false; Cleanup(); Plugin.L.LogWarning((object)("[REST] stand menu failed: " + ex)); } } private static InteractablePreset? ChairPreset() { if ((SoCustomComparison)(object)chairPreset != (SoCustomComparison)null) { return chairPreset; } foreach (Object item in (Il2CppArrayBase)(object)Resources.FindObjectsOfTypeAll(Il2CppType.Of())) { InteractablePreset val = ((Il2CppObjectBase)item).TryCast(); if ((SoCustomComparison)(object)val != (SoCustomComparison)null && ((Object)val).name == "Chair") { chairPreset = val; break; } } return chairPreset; } private static void Cleanup() { try { Interactable? spot = Spot; if (spot != null) { spot.SafeDelete(false); } } catch { } Spot = null; try { if ((Object)(object)spotObject != (Object)null) { Object.Destroy((Object)(object)spotObject); } } catch { } spotObject = null; } internal static void Close() { Active = false; try { Player.Instance.SetSettingAlarmMode(false); } catch { } try { InteractionController.Instance.SetLockedInInteractionMode((Interactable)null, 0, false); } catch { } Cleanup(); HoldUntil = Time.unscaledTime + 1f; StartGuard(); Plugin.L.LogInfo((object)"[REST] stand menu: got up"); } } [HarmonyPatch] internal static class StandMenuPatches { [HarmonyPatch(typeof(Interactable), "GetName")] [HarmonyPostfix] private static void Name(Interactable __instance, ref string __result) { Interactable spot = StandMenu.Spot; if (spot != null && ((Il2CppObjectBase)__instance).Pointer == ((Il2CppObjectBase)spot).Pointer) { __result = "Watch"; } } [HarmonyPatch(typeof(Player), "TransformPlayerController")] [HarmonyPrefix] private static bool NoReturnWrite(Interactable newInteractable) { Interactable spot = StandMenu.Spot; if (spot != null && newInteractable != null && ((Il2CppObjectBase)newInteractable).Pointer == ((Il2CppObjectBase)spot).Pointer) { Plugin.L.LogInfo((object)"[REST] standing rest: seat transition skipped, you stay where you are"); return false; } return true; } [HarmonyPatch(typeof(Player), "ReturnFromTransform")] [HarmonyPrefix] private static bool NoReturnMove() { if (StandMenu.Active || Time.unscaledTime < StandMenu.HoldUntil) { Plugin.L.LogInfo((object)"[REST] standing rest: return from seat skipped"); return false; } return true; } private static bool Holding() { if (!StandMenu.Active && !StandMenu.InGuard) { return Time.unscaledTime < StandMenu.HoldUntil; } return true; } [HarmonyPatch(typeof(PlayerUnstuck), "Update")] [HarmonyPrefix] private static void NotStuck(PlayerUnstuck __instance) { if (Holding()) { try { __instance.currentAttemptedSecondsOfMovement = 0f; } catch { } } } [HarmonyPatch(typeof(PlayerUnstuck), "UnstuckTeleportPlayer")] [HarmonyPrefix] private static bool NoUnstuck() { if (!Holding()) { return true; } Plugin.L.LogInfo((object)"[REST] blocked the game's unstuck teleport"); return false; } [HarmonyPatch(typeof(ActionController), "Return")] [HarmonyPrefix] private static bool Return() { if (!StandMenu.Active) { return true; } StandMenu.Close(); return false; } } internal static class SkipPrompts { internal const string Hour = "Skip One Hour"; internal const string All = "Skip To Alarm"; private static InteractionAction? all; private static bool swapLogged; private static bool logged; private static InteractionAction? runAll; private static InteractionAction? runHour; internal static InteractionAction? toggleSrc; internal static InteractionAction? forwardSrc; private static bool runLogged; internal static void Swap(Dictionary? table) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) if (table == null || !Plugin.ReplaceHoursToggle.Value) { return; } Enumerator enumerator = table.GetEnumerator(); bool flag = default(bool); while (enumerator.MoveNext()) { KeyValuePair current = enumerator.Current; InteractableCurrentAction value = current.Value; InteractionAction val = ((value != null) ? value.currentAction : null); if (((val != null) ? val.interactionName : null) != "Switch Hours/Minutes") { continue; } if (all == null) { all = Copy(val, "Skip To Alarm", val.useDefaultKeySetting, val.keyOverride); } current.Value.currentAction = all; if (!swapLogged) { swapLogged = true; ManualLogSource l = Plugin.L; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(38, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[REST] prompt on "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(current.Key); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" is now Skip To Alarm"); } l.LogInfo(val2); } } } internal static void AddTo(List? acts) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) if (acts == null || !Plugin.ReplaceHoursToggle.Value) { return; } AddRunning(acts); bool flag = false; int num = -1; for (int i = 0; i < acts.Count; i++) { InteractionAction obj = acts[i]; string text = ((obj != null) ? obj.interactionName : null); if (text == "Skip To Alarm") { return; } if (text == "Alarm Forward") { flag = true; if (forwardSrc == null) { forwardSrc = acts[i]; } } if (text == "Switch Hours/Minutes") { num = i; if (toggleSrc == null) { toggleSrc = acts[i]; } } } if (flag && num >= 0) { InteractionAction val = acts[num]; if (all == null) { all = Copy(val, "Skip To Alarm", val.useDefaultKeySetting, val.keyOverride); } acts[num] = all; if (!logged) { logged = true; Plugin.L.LogInfo((object)"[REST] Skip To Alarm replaces Switch Hours/Minutes in the pass-time menu"); } } } private static void AddRunning(List acts) { //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown bool flag = false; try { flag = (Object)(object)Player.Instance != (Object)null && Player.Instance.spendingTimeMode && !Player.Instance.setAlarmMode; } catch { } if (!flag) { for (int num = acts.Count - 1; num >= 0; num--) { if (acts[num] != null && ((runAll != null && ((Il2CppObjectBase)acts[num]).Pointer == ((Il2CppObjectBase)runAll).Pointer) || (runHour != null && ((Il2CppObjectBase)acts[num]).Pointer == ((Il2CppObjectBase)runHour).Pointer))) { acts.RemoveAt(num); } } return; } InteractionAction val = null; for (int i = 0; i < acts.Count; i++) { InteractionAction obj2 = acts[i]; switch ((obj2 != null) ? obj2.interactionName : null) { case "Skip One Hour": return; case "Cancel": val = acts[i]; break; } } if (val == null) { return; } if (toggleSrc != null) { if (runAll == null) { runAll = Slot(Mixed(val, toggleSrc, "Skip To Alarm"), Plugin.PromptAlarmSlot.Value); } acts.Add(runAll); } if (forwardSrc != null) { if (runHour == null) { runHour = Slot(Mixed(val, forwardSrc, "Skip One Hour"), Plugin.PromptHourSlot.Value); } acts.Add(runHour); } if (!runLogged) { runLogged = true; ManualLogSource l = Plugin.L; bool flag2 = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(64, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[REST] prompts added while resting (alarm source "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(toggleSrc != null); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", hour source "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(forwardSrc != null); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")"); } l.LogInfo(val2); } } private static InteractionAction Slot(InteractionAction a, string slot) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0018: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrWhiteSpace(slot) && Enum.TryParse(slot.Trim(), ignoreCase: true, out InteractionKey result) && (int)result != 0) { a.useDefaultKeySetting = false; a.keyOverride = result; } ManualLogSource l = Plugin.L; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(20, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[REST] prompt '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(a.interactionName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' on "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(a.useDefaultKeySetting ? "its default button" : ((object)a.keyOverride/*cast due to .constrained prefix*/).ToString()); } l.LogInfo(val); return a; } private static InteractionAction Mixed(InteractionAction shown, InteractionAction does, string name) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) InteractionAction obj = Copy(shown, name, does.useDefaultKeySetting, does.keyOverride); obj.action = does.action; return obj; } private static InteractionAction Copy(InteractionAction src, string name, bool useDefault, InteractionKey key) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown return new InteractionAction { interactionName = name, action = src.action, useDefaultKeySetting = useDefault, keyOverride = key, onlyActiveIf = src.onlyActiveIf, effectSwitchStates = new List(), availableWhileLockedIn = src.availableWhileLockedIn, availableWhileIllegal = true, availableWhileWitnessesToIllegal = true, specialCase = src.specialCase }; } } [HarmonyPatch] internal static class SkipPromptPatches { [HarmonyPatch(typeof(Interactable), "UpdateCurrentActions")] [HarmonyPostfix] private static void Current(Interactable __instance) { try { SkipPrompts.Swap(__instance.currentActions); } catch { } } [HarmonyPatch(typeof(InteractablePreset), "GetActions")] [HarmonyPostfix] private static void Actions(List __result) { try { SkipPrompts.AddTo(__result); } catch { } } [HarmonyPatch(typeof(Interactable), "OnInteraction", new Type[] { typeof(InteractionAction), typeof(Actor), typeof(bool), typeof(float) })] [HarmonyPrefix] private static bool Pressed(InteractionAction action) { string text = ((action != null) ? action.interactionName : null); if ((text == "Skip One Hour" || text == "Skip To Alarm") && !Rest.Debounce()) { return false; } if (text == "Skip One Hour") { Rest.Skip(1f, "one hour"); return false; } if (text == "Skip To Alarm") { float num = Rest.AlarmHoursAhead(); if (num <= 0.01f) { Rest.Note("Set the alarm on your watch first."); } else { Rest.Skip(num, "the alarm"); } return false; } return true; } } [HarmonyPatch] internal static class SkipButtonPatches { private const string From = "Switch Hours/Minutes"; private static bool busy; private static bool InAlarmMenu() { try { Player instance = Player.Instance; return (Object)(object)instance != (Object)null && (instance.setAlarmMode || StandMenu.Active || InteractionController.Instance.lockedInInteraction != null); } catch { return false; } } [HarmonyPatch(typeof(ActionController), "HoursMinutesToggle")] [HarmonyPrefix] private static bool Toggle() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown if (!Plugin.ReplaceHoursToggle.Value || !InAlarmMenu()) { return true; } if (!Rest.Debounce()) { return false; } float num = Rest.AlarmHoursAhead(); ManualLogSource l = Plugin.L; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(38, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[REST] Skip To Alarm pressed, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num, "0.00"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" h ahead"); } l.LogInfo(val); if (num <= 0.01f) { Rest.Note("Set the alarm on your watch first."); } else { Rest.Skip(num, "the alarm"); } return false; } [HarmonyPatch(typeof(ActionController), "WatchForward")] [HarmonyPrefix] private static bool Forward() { bool flag = false; try { flag = Player.Instance.spendingTimeMode && !Player.Instance.setAlarmMode; } catch { } if (!flag) { return true; } if (Rest.Debounce()) { Rest.Skip(1f, "one hour"); } return false; } private static void Relabel(ControlDisplayController c) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (busy || !Plugin.ReplaceHoursToggle.Value || (Object)(object)c == (Object)null) { return; } try { string actionName = c.actionName; if (actionName != null && actionName.Contains("Switch Hours/Minutes")) { busy = true; c.SetControlText(c.key, actionName.Replace("Switch Hours/Minutes", "Skip To Alarm"), false); } } catch { } finally { busy = false; } } [HarmonyPatch(typeof(ControlDisplayController), "UpdateDisplay")] [HarmonyPostfix] private static void Display(ControlDisplayController __instance) { Relabel(__instance); } [HarmonyPatch(typeof(ControlDisplayController), "SetControlText")] [HarmonyPostfix] private static void Text(ControlDisplayController __instance) { Relabel(__instance); } } [HarmonyPatch(typeof(Strings), "Get")] internal static class PromptText { private static void Postfix(string key, ref string __result) { if (key == "Skip To Alarm") { __result = key + " (R)"; } else if (key == "Skip One Hour") { __result = key + " (" + Plugin.WatchKey.Value + ")"; } } } }