Static preferences store for the Socer game. Reads and writes language, sound volume, text size, dialogue censorship, tutorial flags, club help bitmask and hotkey bindings to a local JSON file, saving after each change.
using Sandbox;
using System;
using System.Collections.Generic;
namespace Socer;
public sealed class GamePreferencesData
{
public string Language {get;set;}="en";
public int SoundVolume {get;set;}=70;
public int TextSizePercent {get;set;}=100;
public int DialogueCensorship {get;set;}=1;
public bool TutorialSeen {get;set;}
public bool MatchTutorialSeen {get;set;}
public int ClubHelpSeen {get;set;}
public Dictionary<string,string> Hotkeys {get;set;}=new();
}
// Stored independently of the career so changing a preference never touches match progress.
public static class GamePreferences
{
// Kept private; editor acceptance can redirect to its own disposable file
// while exercising the normal preference setters and automatic saving.
static string FileName="socer-preferences-v1.json";
public static string Language {get;private set;}="en";
public static bool Russian=>Language=="ru";
public static int SoundVolume {get;private set;}=70;
public static int TextSizePercent {get;private set;}=100;
public static DialogueCensorship Censorship {get;private set;}=DialogueCensorship.Masked;
public static string TextSizeClass=>TextSizePercent switch {115=>"text-size-115",130=>"text-size-130",_=>"text-size-100"};
public static int TextSizeRevision {get;private set;}
public static bool TutorialSeen {get;private set;}
public static bool MatchTutorialSeen {get;private set;}
public static int ClubHelpSeen {get;private set;}
public static int Revision {get;private set;}
public static void Load()
{
try
{
var data=FileSystem.Data.ReadJson<GamePreferencesData>(FileName);
Language=data?.Language=="ru"?"ru":"en";
SoundVolume=Math.Clamp(data?.SoundVolume??70,0,100);
TextSizePercent=NormalizeTextSize(data?.TextSizePercent??100);
Censorship=DialogueFilter.Normalize(data?.DialogueCensorship??1);
TutorialSeen=data?.TutorialSeen??false;
MatchTutorialSeen=data?.MatchTutorialSeen??false;
ClubHelpSeen=(data?.ClubHelpSeen??0)&ClubHelp.AllTopics;
GameHotkeys.LoadBindings(data?.Hotkeys);
if(data?.DialogueCensorship==2)Save();
}
catch(Exception e){Log.Warning($"Socer preferences: {e.Message}");Language="en";SoundVolume=70;TextSizePercent=100;Censorship=DialogueCensorship.Masked;TutorialSeen=false;MatchTutorialSeen=false;ClubHelpSeen=0;GameHotkeys.LoadBindings(null);}
TextSizeRevision++;
Revision++;
}
public static void SetLanguage(string language)
{
language=language=="ru"?"ru":"en";
if(Language==language)return;
Language=language;GameHotkeys.ClearStatus();Revision++;Save();
}
public static void SetSoundVolume(int volume)
{
volume=Math.Clamp(volume,0,100);
if(SoundVolume==volume)return;
SoundVolume=volume;Revision++;Save();
}
// Invalid old/custom values always resolve to one of the three supported layouts.
public static void SetCensorship(DialogueCensorship value)
{
value=DialogueFilter.Normalize((int)value);
if(Censorship==value)return;
Censorship=value;Revision++;Save();
}
public static int NormalizeTextSize(int percent)
{
if(percent<100)return 100;
if(percent>130)return 130;
return percent<108?100:percent<123?115:130;
}
public static void SetTextSize(int percent)
{
percent=NormalizeTextSize(percent);
if(TextSizePercent==percent)return;
TextSizePercent=percent;TextSizeRevision++;Revision++;Save();
}
public static void MarkTutorialSeen()
{
if(TutorialSeen)return;
TutorialSeen=true;Revision++;Save();
}
public static void MarkMatchTutorialSeen()
{
if(MatchTutorialSeen)return;
MatchTutorialSeen=true;Revision++;Save();
}
public static bool HasSeenClubHelp(ClubHelpTopic topic)=>topic==ClubHelpTopic.None || (ClubHelpSeen&(int)topic)!=0;
public static void MarkClubHelpSeen(ClubHelpTopic topic)
{
if(ClubHelp.Get(topic)==null || HasSeenClubHelp(topic))return;
ClubHelpSeen|=(int)topic;Revision++;Save();
}
public static void ResetClubHelp()
{
if(ClubHelpSeen==0)return;
ClubHelpSeen=0;Revision++;Save();
}
internal static bool SaveHotkeys()
{
bool saved=Save();if(saved)Revision++;return saved;
}
static bool Save()
{
try
{
var data=new GamePreferencesData{Language=Language,SoundVolume=SoundVolume,TextSizePercent=TextSizePercent,
DialogueCensorship=(int)Censorship,TutorialSeen=TutorialSeen,MatchTutorialSeen=MatchTutorialSeen,
ClubHelpSeen=ClubHelpSeen,Hotkeys=GameHotkeys.ExportBindings()};
FileSystem.Data.WriteJson(FileName,data);return true;
}
catch(Exception e){Log.Warning($"Could not save Socer preferences: {e.Message}");return false;}
}
}