164 lines
4.3 KiB
C#
164 lines
4.3 KiB
C#
using NeoModLoader.services;
|
|
using UnityEngine;
|
|
|
|
namespace IdleSpectator;
|
|
|
|
/// <summary>
|
|
/// ManualControl vs SpectatorMode toggle (I).
|
|
/// </summary>
|
|
public static class SpectatorMode
|
|
{
|
|
public const KeyCode ToggleKey = KeyCode.I;
|
|
|
|
public static bool Active { get; private set; }
|
|
|
|
/// <summary>
|
|
/// True when idle was frozen for Lore/browse without wiping StoryPlanner / registry.
|
|
/// Resume via <see cref="SetActive"/>(true) restores that session instead of a full clear enable.
|
|
/// </summary>
|
|
public static bool BrowsePaused { get; private set; }
|
|
|
|
private static bool _forceFileChecked;
|
|
|
|
public static void Toggle()
|
|
{
|
|
SetActive(!Active);
|
|
}
|
|
|
|
/// <param name="browsePause">
|
|
/// When disabling: freeze story/crisis/ledger/registry for Lore browse (do not Clear).
|
|
/// Ignored when enabling - resume uses <see cref="BrowsePaused"/>.
|
|
/// </param>
|
|
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();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Optional one-shot: place an empty <c>.force-on</c> file in the mod folder to enable Spectator once (deleted after use).
|
|
/// </summary>
|
|
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);
|
|
}
|
|
}
|