public static void UpdateSettings(bool readSettings = true) { if (readSettings) { userSettings = modConfig.Read(); } modConfig.Write(userSettings); // Write any settings that the user doesn't have in their settings file. // Apply overrides settings = modConfig.Read(); if (settings.DisableAdvantageous) { settings.BombHUD = false; settings.MissionSeed = -1; settings.Mode = Mode.Normal; settings.ShowEdgework = false; } }
/// <summary> /// Starts all tweak runners. /// </summary> private static void StartTweaks() { HashSet <string> tweakIds = new HashSet <string>(); // Create runners for all the tweaks foreach (Type tweakType in allTweakTypes) { // Verify tweaks do not have conflicting IDs RegisterTweakAttribute registerAttribute = tweakType.GetCustomAttribute <RegisterTweakAttribute>(); if (tweakIds.Contains(registerAttribute.Id)) { throw new InvalidOperationException( "Found conflicting tweaks with the ID '{0}', "); } // Create the tweak ConstructorInfo constructor = tweakType.GetConstructor(new Type[] { }); Tweak tweak = (Tweak)constructor.Invoke(null); TweakSettings settings = synchronizer.GetSettingsForType(registerAttribute.SettingsType); // Create and register the runner TweakRunner runner = new TweakRunner(tweak, settings); tweakRunners.Add(runner); synchronizer.Register(runner.Tweak); synchronizer.Register(runner.TweakMetadata.PatchesType); } // Sync patch/tweak references with their respective settings synchronizer.Sync(); // Start all runners foreach (TweakRunner runner in tweakRunners) { runner.Start(); } }
public static void UpdateSettings() { settings = modConfig.Settings; modConfig.Settings = settings; // Write any settings that the user doesn't have in their settings file. }
void Awake() { MainThreadQueue.Initialize(); GameInfo = GetComponent <KMGameInfo>(); SettingWarning = transform.Find("UI").Find("SettingWarning").gameObject; BetterCasePicker.BombCaseGenerator = GetComponentInChildren <BombCaseGenerator>(); modConfig = new ModConfig <TweakSettings>("TweakSettings"); settings = modConfig.Settings; modConfig.Settings = settings; // Write any settings that the user doesn't have in their settings file. bool changeFadeTime = settings.FadeTime >= 0; FreeplayDevice.MAX_SECONDS_TO_SOLVE = float.MaxValue; FreeplayDevice.MIN_MODULE_COUNT = 1; if (settings.EnableModsOnlyKey) { var lastFreeplaySettings = FreeplaySettings.CreateDefaultFreeplaySettings(); lastFreeplaySettings.OnlyMods = true; ProgressionManager.Instance.RecordLastFreeplaySettings(lastFreeplaySettings); } UpdateSettingWarning(); // Setup API/properties other mods to interact with GameObject infoObject = new GameObject("Tweaks_Info", typeof(TweaksProperties)); infoObject.transform.parent = gameObject.transform; // Watch the TweakSettings file for Time Mode state being changed in the office. FileSystemWatcher watcher = new FileSystemWatcher(Path.Combine(Application.persistentDataPath, "Modsettings"), "TweakSettings.json") { NotifyFilter = NotifyFilters.LastWrite }; watcher.Changed += (object source, FileSystemEventArgs e) => { if (settings.Equals(modConfig.Settings)) { return; } UpdateSettings(); UpdateSettingWarning(); MainThreadQueue.Enqueue(() => StartCoroutine(ModifyFreeplayDevice(false))); }; // Setup our "service" to block the leaderboard submission requests ReflectedTypes.InstanceField.SetValue(null, new SteamFilterService()); // Create a fake case with a bunch of anchors to trick the game when using CaseGenerator. TweaksCaseGeneratorCase = new GameObject("TweaksCaseGenerator"); TweaksCaseGeneratorCase.transform.SetParent(transform); var kmBomb = TweaksCaseGeneratorCase.AddComponent <KMBomb>(); kmBomb.IsHoldable = false; kmBomb.WidgetAreas = new List <GameObject>(); kmBomb.visualTransform = transform; kmBomb.Faces = new List <KMBombFace>(); TweaksCaseGeneratorCase.AddComponent <ModBomb>(); var kmBombFace = TweaksCaseGeneratorCase.AddComponent <KMBombFace>(); kmBombFace.Anchors = new List <Transform>(); kmBomb.Faces.Add(kmBombFace); for (int i = 0; i <= 9001; i++) { kmBombFace.Anchors.Add(transform); } // Handle scene changes UnityEngine.SceneManagement.SceneManager.sceneLoaded += (Scene scene, LoadSceneMode _) => { UpdateSettings(); UpdateSettingWarning(); Modes.settings = Modes.modConfig.Settings; Modes.modConfig.Settings = Modes.settings; if ((scene.name == "mainScene" || scene.name == "gameplayScene") && changeFadeTime) { SceneManager.Instance.RapidFadeInTime = settings.FadeTime; } switch (scene.name) { case "mainScene": if (changeFadeTime) { SceneManager.Instance.SetupState.FadeInTime = SceneManager.Instance.SetupState.FadeOutTime = SceneManager.Instance.UnlockState.FadeInTime = settings.FadeTime; } break; case "gameplayLoadingScene": var gameplayLoadingManager = FindObjectOfType <GameplayLoadingManager>(); if (settings.InstantSkip) { gameplayLoadingManager.MinTotalLoadTime = 0; } if (changeFadeTime) { gameplayLoadingManager.FadeInTime = gameplayLoadingManager.FadeOutTime = settings.FadeTime; } ReflectedTypes.UpdateTypes(); ReflectedTypes.CurrencyAPIEndpointField?.SetValue(null, settings.FixFER ? "http://api.exchangeratesapi.io" : "http://api.fixer.io"); break; case "gameplayScene": if (changeFadeTime) { SceneManager.Instance.GameplayState.FadeInTime = SceneManager.Instance.GameplayState.FadeOutTime = settings.FadeTime; } break; } }; // Handle state changes GameInfo.OnStateChange += (KMGameInfo.State state) => { CurrentState = state; watcher.EnableRaisingEvents = state == KMGameInfo.State.Setup; if (state == KMGameInfo.State.Gameplay) { bool disableRecords = settings.BombHUD || settings.ShowEdgework || CurrentMode != Mode.Normal || settings.MissionSeed != -1; Assets.Scripts.Stats.StatsManager.Instance.DisableStatChanges = Assets.Scripts.Records.RecordManager.Instance.DisableBestRecords = disableRecords; if (disableRecords) { SteamFilterService.TargetMissionID = GameplayState.MissionToLoad; } BetterCasePicker.HandleCaseGeneration(); BombStatus.Instance.widgetsActivated = false; BombStatus.Instance.HUD.SetActive(settings.BombHUD); BombStatus.Instance.Edgework.SetActive(settings.ShowEdgework); BombStatus.Instance.ConfidencePrefab.gameObject.SetActive(CurrentMode != Mode.Zen); BombStatus.Instance.StrikesPrefab.color = CurrentMode == Mode.Time ? Color.yellow : Color.red; Modes.Multiplier = Modes.settings.TimeModeStartingMultiplier; BombStatus.Instance.UpdateMultiplier(); bombWrappers = new BombWrapper[] { }; StartCoroutine(CheckForBombs()); if (settings.SkipGameplayDelay) { StartCoroutine(SkipGameplayDelay()); } if (GameplayState.BombSeedToUse == -1) { GameplayState.BombSeedToUse = settings.MissionSeed; } } else if (state == KMGameInfo.State.Setup) { if (ReflectedTypes.LoadedModsField.GetValue(ModManager.Instance) is Dictionary <string, Mod> loadedMods) { Mod tweaksMod = loadedMods.Values.FirstOrDefault(mod => mod.ModID == "Tweaks"); if (tweaksMod != null) { if (CaseGeneratorSettingCache != settings.CaseGenerator) { if (settings.CaseGenerator) { tweaksMod.ModObjects.Add(TweaksCaseGeneratorCase); } else { tweaksMod.ModObjects.Remove(TweaksCaseGeneratorCase); } CaseGeneratorSettingCache = settings.CaseGenerator; UpdateSettingWarning(); } } } StartCoroutine(ModifyFreeplayDevice(true)); GetComponentInChildren <ModSelectorExtension>().FindAPI(); GameplayState.BombSeedToUse = -1; } else if (state == KMGameInfo.State.Transitioning) { // Because the settings are checked on a scene change and there is no scene change from exiting the gameplay room, // we need to update the settings here in case the user changed their HideTOC settings. UpdateSettings(); bool modified = false; var ModMissionToCs = ModManager.Instance.ModMissionToCs; foreach (var metaData in ModMissionToCs) { modified |= ModToCMetaData.Add(metaData); } var unloadedMods = (Dictionary <string, Mod>)ReflectedTypes.UnloadedModsField.GetValue(ModManager.Instance); if (unloadedMods != null) { foreach (var unloadedMod in unloadedMods.Values) { var tocs = (List <ModTableOfContentsMetaData>)ReflectedTypes.TocsField.GetValue(unloadedMod); if (tocs != null) { foreach (var metaData in tocs) { modified |= ModToCMetaData.Remove(metaData); } } } } var newToCs = ModToCMetaData.Where(metaData => !settings.HideTOC.Any(pattern => Localization.GetLocalizedString(metaData.DisplayNameTerm).Like(pattern))); modified |= (newToCs.Count() != ModMissionToCs.Count || !newToCs.All(ModMissionToCs.Contains)); ModMissionToCs.Clear(); ModMissionToCs.AddRange(newToCs); if (modified) { SetupState.LastBombBinderTOCIndex = 0; SetupState.LastBombBinderTOCPage = 0; } } }; }