using System.IO;
using NeoModLoader.api;
using NeoModLoader.constants;
using NeoModLoader.services;
namespace IdleSpectator;
///
/// NML ModConfig accessors for Idle Spectator.
///
public static class ModSettings
{
public const string GroupId = "Spectator";
public const string EnabledId = "enabled";
public const string ShowWatchReasonsId = "show_watch_reasons";
public const string ShowDossierCaptionId = "show_dossier_caption";
public const string ChronicleEnabledId = "chronicle_enabled";
public const string DebugStateProbeId = "debug_state_probe";
public const string GravestonesEnabledId = "gravestones_enabled";
public const string GravestoneMaxStacksId = "gravestone_max_stacks";
public const string GravestoneTtlSecondsId = "gravestone_ttl_seconds";
public const int DefaultGravestoneMaxStacks = 1000;
public const int DefaultGravestoneTtlSeconds = 300;
private static ModConfig _config;
public static bool Enabled => GetBool(EnabledId, defaultValue: true);
public static bool ShowWatchReasons => GetBool(ShowWatchReasonsId, defaultValue: true);
public static bool ShowDossierCaption => GetBool(ShowDossierCaptionId, defaultValue: true);
public static bool ChronicleEnabled => GetBool(ChronicleEnabledId, defaultValue: true);
public static bool DebugStateProbe => GetBool(DebugStateProbeId, defaultValue: true);
public static bool GravestonesEnabled => GetBool(GravestonesEnabledId, defaultValue: true);
public static int GravestoneMaxStacks =>
GetInt(GravestoneMaxStacksId, DefaultGravestoneMaxStacks, min: 0, max: 2000);
public static int GravestoneTtlSeconds =>
GetInt(GravestoneTtlSecondsId, DefaultGravestoneTtlSeconds, min: 30, max: 1800);
public static ModConfig Load(ModDeclare declare)
{
string persistentPath = Path.Combine(Paths.ModsConfigPath, declare.UID + ".config");
ModConfig persistent = new ModConfig(persistentPath, pIsPersistent: true);
string defaultsPath = Path.Combine(declare.FolderPath, Paths.ModDefaultConfigFileName);
if (File.Exists(defaultsPath))
{
ModConfig defaults = new ModConfig(defaultsPath);
persistent.MergeWith(defaults);
}
_config = persistent;
return _config;
}
/// NML config callback: IdleSpectator.ModSettings:OnEnabledChanged
public static void OnEnabledChanged(bool enabled)
{
if (!enabled && SpectatorMode.Active)
{
SpectatorMode.SetActive(false);
LogService.LogInfo("[IdleSpectator] Disabled via settings");
}
if (!enabled)
{
GraveMarkers.Clear();
}
}
public static bool TrySetBool(string id, bool value)
{
if (_config == null || string.IsNullOrEmpty(id))
{
return false;
}
try
{
ModConfigItem item = _config[GroupId][id];
item.SetValue(value);
// Ensure settings callbacks apply even if NML does not fire them from SetValue.
if (id == EnabledId)
{
OnEnabledChanged(value);
}
return true;
}
catch (System.Exception ex)
{
LogService.LogInfo($"[IdleSpectator] TrySetBool failed for {id}: {ex.Message}");
return false;
}
}
public static bool TrySetInt(string id, int value)
{
if (_config == null || string.IsNullOrEmpty(id))
{
return false;
}
try
{
ModConfigItem item = _config[GroupId][id];
item.SetValue(value);
return true;
}
catch (System.Exception ex)
{
LogService.LogInfo($"[IdleSpectator] TrySetInt failed for {id}: {ex.Message}");
return false;
}
}
private static bool GetBool(string id, bool defaultValue)
{
if (_config == null)
{
return defaultValue;
}
try
{
ModConfigItem item = _config[GroupId][id];
object value = item.GetValue();
if (value is bool b)
{
return b;
}
}
catch
{
// Fall through to default.
}
return defaultValue;
}
private static int GetInt(string id, int defaultValue, int min, int max)
{
if (_config == null)
{
return UnityEngine.Mathf.Clamp(defaultValue, min, max);
}
try
{
ModConfigItem item = _config[GroupId][id];
object value = item.GetValue();
if (value is int i)
{
return UnityEngine.Mathf.Clamp(i, min, max);
}
if (value is long l)
{
return UnityEngine.Mathf.Clamp((int)l, min, max);
}
if (value is float f)
{
return UnityEngine.Mathf.Clamp(UnityEngine.Mathf.RoundToInt(f), min, max);
}
}
catch
{
// Fall through to default.
}
return UnityEngine.Mathf.Clamp(defaultValue, min, max);
}
}