using NeoModLoader.services; using UnityEngine; namespace IdleSpectator; /// /// ManualControl vs SpectatorMode toggle (I). /// public static class SpectatorMode { public const KeyCode ToggleKey = KeyCode.I; public static bool Active { get; private set; } /// /// True when idle was frozen for Lore/browse without wiping StoryPlanner / registry. /// Resume via (true) restores that session instead of a full clear enable. /// public static bool BrowsePaused { get; private set; } private static bool _forceFileChecked; public static void Toggle() { SetActive(!Active); } /// /// When disabling: freeze story/crisis/ledger/registry for Lore browse (do not Clear). /// Ignored when enabling - resume uses . /// public static void SetActive(bool active, bool quiet = false, bool browsePause = false) { if (active && !ModSettings.Enabled) { LogService.LogInfo("[IdleSpectator] Enable blocked: disabled in settings"); return; } if (Active == active) { return; } Active = active; if (Active) { WatchCaption.ClearPausePin(); bool fromBrowse = BrowsePaused; BrowsePaused = false; if (fromBrowse) { InterestDirector.OnSpectatorBrowseResumed(); } else { InterestDirector.OnSpectatorEnabled(); } SpeciesDiscovery.OnSpectatorEnabled(); Chronicle.OnSpectatorEnabled(); ChronicleHud.OnIdleResumed(); FocusRelationshipArrows.OnSpectatorEnabled(); LogService.LogInfo( fromBrowse ? "[IdleSpectator] Spectator resumed after Lore/browse pause" : "[IdleSpectator] Spectator mode enabled (I or any input to stop; L for Lore)"); } else { if (browsePause) { BrowsePaused = true; InterestDirector.OnSpectatorBrowsePaused(); } else { BrowsePaused = false; InterestDirector.OnSpectatorDisabled(); } SpeciesDiscovery.OnSpectatorDisabled(); FocusRelationshipArrows.OnSpectatorDisabled(); CameraDirector.ClearFollow(); if (quiet) { // Manual-input / Lore pause: leave dossier up so ShowStatusBanner can reuse it. StateProbe.Reset(); } else { WatchCaption.Clear(); StateProbe.Reset(); LogService.LogInfo("[IdleSpectator] Spectator mode disabled"); } } } public static void PollInput() { if (!Config.game_loaded) { return; } if (!ModSettings.Enabled) { if (Active) { SetActive(false); } return; } TryForceOnFile(); if (Input.GetKeyDown(ToggleKey)) { // Manual I while Lore is open must not be undone by Lore close auto-resume. if (ChronicleHud.Visible) { ChronicleHud.NotifyManualIdleToggle(); } Toggle(); } } /// /// Optional one-shot: place an empty .force-on file in the mod folder to enable Spectator once (deleted after use). /// private static void TryForceOnFile() { if (_forceFileChecked || Active || !ModSettings.Enabled) { return; } string modFolder = ModClass.ModFolder; if (string.IsNullOrEmpty(modFolder)) { return; } string path = System.IO.Path.Combine(modFolder, ".force-on"); if (!System.IO.File.Exists(path)) { return; } _forceFileChecked = true; try { System.IO.File.Delete(path); } catch { // Still enable even if delete fails. } SetActive(true); } }