void NetOffice.Tools.Native.IDTExtensibility2.OnStartupComplete(ref Array custom) { try { Tweaks.ApplyTweaks(Factory, this, Type, "PowerPoint", IsLoadedFromSystem); LoadingTimeElapsed = (DateTime.Now - _creationTime); Roots = OnCreateRoots(); RaiseOnStartupComplete(ref custom); } catch (NetRuntimeSystem.Exception exception) { NetOffice.DebugConsole.Default.WriteException(exception); OnError(ErrorMethodKind.OnStartupComplete, exception); } }
public static IEnumerator LoadDefaultSettings() { UnityWebRequest www = UnityWebRequest.Get("https://spreadsheets.google.com/feeds/list/16lz2mCqRWxq__qnamgvlD0XwTuva4jIDW1VPWX49hzM/1/public/values?alt=json"); yield return(www.SendWebRequest()); if (!www.isNetworkError && !www.isHttpError) { bool missingWarning = false; foreach (var entry in JObject.Parse(www.downloadHandler.text)["feed"]["entry"]) { bool score = !string.IsNullOrEmpty(entry["gsx$resolvedscore"]["$t"]?.Value <string>().Trim()); bool multiplier = !string.IsNullOrEmpty(entry["gsx$resolvedbosspointspermodule"]["$t"]?.Value <string>().Trim()); if (entry["gsx$moduleid"] == null) { if ((score || multiplier) && !missingWarning) { missingWarning = true; Tweaks.Log("An entry on the spreadsheet is missing it's module ID. You should contact the spreadsheet maintainers about this."); } continue; } string moduleID = entry["gsx$moduleid"].Value <string>("$t"); if (string.IsNullOrEmpty(moduleID) || moduleID == "ModuleID") { continue; } if (score) { DefaultComponentValues[moduleID] = entry["gsx$resolvedscore"].Value <double>("$t"); } if (multiplier) { DefaultTotalModulesMultiplier[moduleID] = entry["gsx$resolvedbosspointspermodule"].Value <double>("$t"); } } } else { Tweaks.Log("Failed to load the default time mode values."); } }
public void OnSolve() { if (!Bomb.IsSolved()) { return; } BombEvents.OnBombSolved -= OnSolve; Tweaks.LogJSON("LFAEvent", new Dictionary <string, object>() { { "type", "BOMB_SOLVE" }, { "serial", bombLogInfo["serial"] }, { "bombTime", CurrentTimer }, { "realTime", Time.unscaledTime - realTimeStart }, { "solves", Bomb.GetSolvedComponentCount() }, { "strikes", Bomb.NumStrikes }, }); }
public void OnDetonate() { if (Bomb.HasDetonated) { return; } BombEvents.OnBombDetonated -= OnDetonate; Tweaks.LogJSON("LFAEvent", new Dictionary <string, object>() { { "type", "BOMB_DETONATE" }, { "serial", bombLogInfo["serial"] }, { "bombTime", CurrentTimer }, { "realTime", Time.unscaledTime - realTimeStart }, { "solves", Bomb.GetSolvedComponentCount() }, { "strikes", Bomb.NumStrikes + (CurrentTimer > 0 ? 1 : 0) }, }); }
private void btnBoost_Click(object sender, EventArgs e) { bool isExcute_WinCleanup; WindowsCleanup.Excute_WindowsCleanup(cbxList_WC, out isExcute_WinCleanup); WindowsServices.ChangeStatusServices(List_SVC, toggleSwitch); bool isExcute_Tweaks; Tweaks.Excute_Tweaks(cbxList_Tweaks, out isExcute_Tweaks); if (SystemInfo.getOSName().Contains("Windows 7") == true && cbxDisableSmartScreen.Checked == true && (cbxDisableSystemRestore.Checked == false && cbxDisableCDBurningFeatures.Checked == false && cbxDisableWinSideBar.Checked == false && cbxSpeedUpMenuShow.Checked == false && cbxSpeedUpShutdown.Checked == false && cbxDisableAutorun.Checked == false)) { isExcute_Tweaks = false; } if (isExcute_WinCleanup == true || isExcute_Tweaks == true) { DevExpress.XtraEditors.XtraMessageBox.Show("Boost Completed.", "Windows Booster", MessageBoxButtons.OK, MessageBoxIcon.Information); } }
IEnumerator GetModuleInformation(BombComponent bombComponent, ModuleTweak moduleTweak = null) { int moduleID = -1; KMBombModule bombModule = bombComponent.GetComponent <KMBombModule>(); string moduleType = Modes.GetModuleID(bombComponent); displayNames[moduleType] = bombComponent.GetModuleDisplayName(); if (bombModule != null) { // Try to find a module ID from a field System.Reflection.FieldInfo idField = ReflectedTypes.GetModuleIDNumber(bombModule, out Component targetComponent); if (idField != null) { // Find the module ID from reflection float startTime = Time.time; yield return(new WaitUntil(() => { moduleID = (int)idField.GetValue(targetComponent); return moduleID != 0 || Time.time - startTime > 30; // Check to see if the field has been initialized with an ID or fail out after 30 seconds. })); } // From the object name. string prefix = bombModule.ModuleDisplayName + " #"; if (moduleID == -1 && bombModule.gameObject.name.StartsWith(prefix) && !int.TryParse(bombModule.gameObject.name.Substring(prefix.Length), out moduleID)) { moduleID = -1; } } // These component types shouldn't try to get the ID from the logger property. Used below. var blacklistedComponents = new[] { ComponentTypeEnum.Empty, ComponentTypeEnum.Mod, ComponentTypeEnum.NeedyMod, ComponentTypeEnum.Timer, }; // From the logger property of vanilla components string loggerName = bombComponent.GetValue <object>("logger")?.GetValue <object>("Logger")?.GetValue <string>("Name"); if (moduleID == -1 && !blacklistedComponents.Contains(bombComponent.ComponentType) && loggerName != null && !int.TryParse(loggerName.Substring(loggerName.IndexOf('#') + 1), out moduleID)) { moduleID = -1; } // From logging implemented by Tweaks if (moduleTweak is ModuleLogging moduleLogging) { moduleID = moduleLogging.moduleID; } if (moduleID != -1) { if (!ids.ContainsKey(moduleType)) { ids[moduleType] = new List <int>(); } ids[moduleType].Add(moduleID); componentIDs[bombComponent] = moduleID; } // Find the index and position of the module's anchor var allAnchors = Bomb.Faces.SelectMany(face => face.Anchors).ToList(); if (allAnchors.Count != 0) // Prevents .First() from being a problem later if there was somehow no anchors. { Transform moduleAnchor = allAnchors.OrderBy(anchor => (anchor.position - bombComponent.transform.position).magnitude).First(); int index = allAnchors.IndexOf(moduleAnchor); modules[index] = moduleID != -1 ? $"{moduleType} {moduleID}" : $"{moduleType} -"; var position = Quaternion.Euler(-Bomb.transform.rotation.eulerAngles) * ((moduleAnchor.position - Bomb.transform.position) / Bomb.Scale); anchors[index] = new decimal[] { Math.Round((decimal)position.x, 3), Math.Round((decimal)position.z, 3) }; // Round using a decimal to make the JSON a bit cleaner. } modulesUnactivated--; if (modulesUnactivated == 0) { Tweaks.LogJSON("LFABombInfo", bombLogInfo); } }
public void Awake() { Bomb = GetComponent <Bomb>(); holdable = Bomb.GetComponentInChildren <FloatingHoldable>(); timerComponent = Bomb.GetTimer(); widgetManager = Bomb.WidgetManager; holdable.OnLetGo += () => BombStatus.Instance.currentBomb = null; Color modeColor = ModeColors[Tweaks.CurrentMode]; BombStatus.Instance.TimerPrefab.color = modeColor; timerComponent.text.color = modeColor; timerComponent.StrikeIndicator.RedColour = modeColor; if (Tweaks.CurrentMode == Mode.Zen) { ZenModeTimePenalty = Mathf.Abs(Modes.settings.ZenModeTimePenalty); ZenModeTimerRate = -timerComponent.GetRate(); timerComponent.SetRateModifier(ZenModeTimerRate); Modes.initialTime = timerComponent.TimeRemaining; //This was in the original code to make sure the bomb didn't explode on the first strike Bomb.NumStrikesToLose++; } realTimeStart = Time.unscaledTime; BombEvents.OnBombDetonated += OnDetonate; BombEvents.OnBombSolved += OnSolve; foreach (BombComponent component in Bomb.BombComponents) { Dictionary <string, object> makeEventInfo(string type) { Dictionary <string, object> eventInfo = new Dictionary <string, object>() { { "type", type }, { "moduleID", Modes.GetModuleID(component) }, { "bombTime", CurrentTimer }, { "realTime", Time.unscaledTime - realTimeStart }, }; if (componentIDs.TryGetValue(component, out int loggingID)) { eventInfo["loggingID"] = loggingID; } return(eventInfo); } component.OnPass += delegate { BombStatus.Instance.UpdateSolves(); var eventInfo = makeEventInfo("PASS"); if (Tweaks.CurrentMode == Mode.Time) { if ( !Modes.settings.ComponentValues.TryGetValue(Modes.GetModuleID(component), out double ComponentValue) && !Modes.DefaultComponentValues.TryGetValue(Modes.GetModuleID(component), out ComponentValue) ) { ComponentValue = 10; } if ( !Modes.settings.TotalModulesMultiplier.TryGetValue(Modes.GetModuleID(component), out double totalModulesMultiplier) && !Modes.DefaultTotalModulesMultiplier.TryGetValue(Modes.GetModuleID(component), out totalModulesMultiplier) ) { totalModulesMultiplier = 0; } var modules = Bomb.GetSolvableComponentCount(); var points = ComponentValue + modules * totalModulesMultiplier; float finalMultiplier = Mathf.Min(Modes.Multiplier, Modes.settings.TimeModeMaxMultiplier); float time = (float)(points * finalMultiplier * Modes.settings.TimeModePointMultiplier); float finalTime = Math.Max(Modes.settings.TimeModeMinimumTimeGained, time); // Show the alert string alertText = ""; if (Math.Round(totalModulesMultiplier, 3) != 0) { alertText += $"{ComponentValue} + {totalModulesMultiplier:0.###} <size=36>x</size> {modules} mods = {points:0}\n"; } string multiplierText = Math.Round(Modes.settings.TimeModePointMultiplier, 3) == 1 ? "" : $"<size=36>x</size> {Modes.settings.TimeModePointMultiplier:0.###} "; alertText += $"{points:0} points <size=36>x</size> {finalMultiplier:0.#} {multiplierText}= {(time > 0 ? "+" : "")}{time.FormatTime()}\n"; if (time < Modes.settings.TimeModeMinimumTimeGained) { alertText += $"Min Time Added = {(finalTime > 0 ? "+" : "")}{finalTime.FormatTime()}\n"; } eventInfo["timeMode"] = alertText.TrimEnd('\n').Replace("<size=36>x</size>", "×"); // Build the logging information for time mode. alertText += component.GetModuleDisplayName(); AddAlert(alertText.Replace(' ', ' '), Color.green); // Replace all spaces with nbsp since we don't want the line to wrap. CurrentTimer += finalTime; Modes.Multiplier += Modes.settings.TimeModeSolveBonus; BombStatus.Instance.UpdateMultiplier(); } Tweaks.LogJSON("LFAEvent", eventInfo); return(false); }; var OnStrike = component.OnStrike; component.OnStrike = (BombComponent source) => { var eventInfo = makeEventInfo("STRIKE"); if (Tweaks.CurrentMode == Mode.Time) { float multiplier = Modes.Multiplier - Modes.settings.TimeModeMultiplierStrikePenalty; float finalMultiplier = Math.Max(multiplier, Modes.settings.TimeModeMinMultiplier); // Show the alert string alertText = $"TIME LOST = {Modes.settings.TimeModeTimerStrikePenalty:0.###} <size=36>x</size> {CurrentTimer.FormatTime()} = {(CurrentTimer * Modes.settings.TimeModeTimerStrikePenalty).FormatTime()}\n"; alertText += $"MULTIPIER = {Modes.Multiplier:0.#} - {Modes.settings.TimeModeMultiplierStrikePenalty:0.#} = {multiplier:0.#}\n"; if (multiplier < Modes.settings.TimeModeMinMultiplier) { alertText += $"REDUCED TO MIN = {finalMultiplier}\n"; } eventInfo["timeMode"] = alertText.TrimEnd('\n').Replace("<size=36>x</size>", "×"); // Build the logging information for time mode. alertText += component.GetModuleDisplayName(); AddAlert(alertText.Replace(' ', ' '), Color.red); Modes.Multiplier = finalMultiplier; BombStatus.Instance.UpdateMultiplier(); if (CurrentTimer < (Modes.settings.TimeModeMinimumTimeLost / Modes.settings.TimeModeTimerStrikePenalty)) { CurrentTimer -= Modes.settings.TimeModeMinimumTimeLost; } else { CurrentTimer -= CurrentTimer * Modes.settings.TimeModeTimerStrikePenalty; } // We can safely set the number of strikes to -1 since it's going to be increased by the game after us. Bomb.NumStrikes = -1; } OnStrike(source); // These mode modifications need to happen after the game handles the strike since they change the timer rate. if (Tweaks.CurrentMode == Mode.Zen) { Bomb.NumStrikesToLose++; ZenModeTimerRate = Mathf.Max(ZenModeTimerRate - Mathf.Abs(Modes.settings.ZenModeTimerSpeedUp), -Mathf.Abs(Modes.settings.ZenModeTimerMaxSpeed)); timerComponent.SetRateModifier(ZenModeTimerRate); CurrentTimer += ZenModeTimePenalty * 60; ZenModeTimePenalty += Mathf.Abs(Modes.settings.ZenModeTimePenaltyIncrease); } if (Tweaks.CurrentMode == Mode.Steady) { timerComponent.SetRateModifier(1); CurrentTimer -= Modes.settings.SteadyModeFixedPenalty * 60 - Modes.settings.SteadyModePercentPenalty * BombStartingTimer; } BombStatus.Instance.UpdateStrikes(); Tweaks.LogJSON("LFAEvent", eventInfo); return(false); }; } var moduleTweaks = new Dictionary <string, Func <BombComponent, ModuleTweak> >() { { "Emoji Math", bombComponent => new EmojiMathLogging(bombComponent) }, { "Probing", bombComponent => new ProbingLogging(bombComponent) }, { "SeaShells", bombComponent => new SeaShellsLogging(bombComponent) }, { "WordScrambleModule", bombComponent => new WordScramblePatch(bombComponent) }, { "Color Decoding", bombComponent => new ColorDecodingTweak(bombComponent) }, { "TurnTheKeyAdvanced", bombComponent => new TTKSTweak(bombComponent) }, { "Wires", bombComponent => new WiresLogging(bombComponent) }, { "Keypad", bombComponent => new KeypadLogging(bombComponent) } }; modules = new string[Bomb.Faces.Sum(face => face.Anchors.Count)]; anchors = new decimal[Bomb.Faces.Sum(face => face.Anchors.Count)][]; bombLogInfo = new Dictionary <string, object>() { { "serial", JsonConvert.DeserializeObject <Dictionary <string, string> >(Bomb.WidgetManager.GetWidgetQueryResponses(KMBombInfo.QUERYKEY_GET_SERIAL_NUMBER, null)[0])["serial"] }, { "displayNames", displayNames }, { "ids", ids }, { "anchors", anchors }, { "modules", modules }, { "timestamp", DateTime.Now.ToString("O") } }; modulesUnactivated = Bomb.BombComponents.Count; foreach (BombComponent component in Bomb.BombComponents) { KMBombModule bombModule = component.GetComponent <KMBombModule>(); if (bombModule != null && (bombModule.ModuleType == "TurnTheKey" || Tweaks.settings.ModuleTweaks)) { switch (bombModule.ModuleType) { // TTK is our favorite Zen mode compatible module // Of course, everything here is repurposed from Twitch Plays. case "TurnTheKey": new TTKComponentSolver(component, bombModule, Tweaks.CurrentMode.Equals(Mode.Zen) ? Modes.initialTime : timerComponent.TimeRemaining); break; // Correct some mispositioned objects in older modules case "ForeignExchangeRates": case "resistors": case "CryptModule": case "LEDEnc": // This fixes the position of the module itself (but keeps the status light in its original location, which fixes it) component.transform.Find("Model").transform.localPosition = new Vector3(0.004f, 0, 0); break; case "Listening": // This fixes the Y-coordinate of the position of the status light component.transform.Find("StatusLight").transform.localPosition = new Vector3(-0.0761f, 0.01986f, 0.075f); break; case "TwoBits": case "errorCodes": case "primeEncryption": case "memorableButtons": case "babaIsWho": case "colorfulDials": case "scalarDials": // This fixes the position of the status light component.GetComponentInChildren <StatusLightParent>().transform.localPosition = new Vector3(0.075167f, 0.01986f, 0.076057f); break; case "tWords": case "moon": case "sun": case "jewelVault": // This fixes the scale of the light components component.GetComponentInChildren <Light>().range *= component.transform.lossyScale.x; break; } // This fixes the position of the highlight switch (bombModule.ModuleType) { case "babaIsWho": case "needlesslyComplicatedButton": component.GetComponent <Selectable>().Highlight.transform.localPosition = Vector3.zero; break; } } ModuleTweak moduleTweak = null; string moduleType = bombModule != null ? bombModule.ModuleType : component.ComponentType.ToString(); if (moduleTweaks.ContainsKey(moduleType) && (moduleType != "WordScrambleModule" || Tweaks.settings.ModuleTweaks)) { moduleTweak = moduleTweaks[moduleType](component); } component.StartCoroutine(GetModuleInformation(component, moduleTweak)); if (component.ComponentType == ComponentTypeEnum.Mod || component.ComponentType == ComponentTypeEnum.NeedyMod) { ReflectedTypes.FindModeBoolean(component); } else if (Tweaks.settings.ModuleTweaks) { switch (component.ComponentType) { case ComponentTypeEnum.Keypad: Tweaks.FixKeypadButtons(((KeypadComponent)component).buttons); break; case ComponentTypeEnum.Simon: Tweaks.FixKeypadButtons(((SimonComponent)component).buttons); break; case ComponentTypeEnum.Password: Tweaks.FixKeypadButtons(component.GetComponentsInChildren <KeypadButton>()); break; case ComponentTypeEnum.NeedyVentGas: Tweaks.FixKeypadButtons(((NeedyVentComponent)component).YesButton, ((NeedyVentComponent)component).NoButton); break; } } } }
public void Awake() { Instance = this; MainThreadQueue.Initialize(); GameInfo = GetComponent <KMGameInfo>(); SettingWarning = gameObject.Traverse("UI", "SettingWarning"); AdvantageousWarning = gameObject.Traverse("UI", "AdvantageousWarning"); Tips.TipMessage = gameObject.Traverse("UI", "TipMessage"); BetterCasePicker.BombCaseGenerator = GetComponentInChildren <BombCaseGenerator>(); DemandBasedLoading.LoadingScreen = gameObject.Traverse <CanvasGroup>("UI", "LoadingModules"); CaseGeneratorWarning = MakeSettingWarning("CaseGenerator"); DBMLWarning = MakeSettingWarning("DemandBasedModLoading"); HoldablesWarning = MakeSettingWarning("Holdables"); modConfig = new ModConfig <TweakSettings>("TweakSettings", OnReadError); UpdateSettings(); StartCoroutine(Modes.LoadDefaultSettings()); DemandBasedLoading.EverLoadedModules = !settings.DemandBasedModLoading; DemandBasedSettingCache = settings.DemandBasedModLoading; HoldablesSettingCache = settings.Holdables; 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); } UpdateSettingWarnings(); AdvantageousWarning.SetActive(false); // Setup API/properties other mods to interact with GameObject infoObject = new GameObject("Tweaks_Info", typeof(TweaksProperties)); infoObject.transform.parent = gameObject.transform; TweaksAPI.Setup(); // 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 (ModConfig <TweakSettings> .SerializeSettings(userSettings) == ModConfig <TweakSettings> .SerializeSettings(modConfig.Read())) { return; } UpdateSettings(); UpdateSettingWarnings(); MainThreadQueue.Enqueue(() => StartCoroutine(ModifyFreeplayDevice(false))); }; // Setup the leaderboard controller to block the leaderboard submission requests. LeaderboardController.Install(); GetTweaks(); // 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(); UpdateSettingWarnings(); Modes.settings = Modes.modConfig.Read(); Modes.modConfig.Write(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"); if ( AdvantageousFeaturesEnabled && GameplayState.MissionToLoad != Assets.Scripts.Missions.FreeplayMissionGenerator.FREEPLAY_MISSION_ID && GameplayState.MissionToLoad != ModMission.CUSTOM_MISSION_ID ) { StartCoroutine(ShowAdvantageousWarning()); } break; case "gameplayScene": if (changeFadeTime) { SceneManager.Instance.GameplayState.FadeInTime = SceneManager.Instance.GameplayState.FadeOutTime = settings.FadeTime; } break; } }; // Handle state changes GameInfo.OnStateChange += (KMGameInfo.State state) => { OnStateChanged(CurrentState, state); // Transitioning away from another state if (state == KMGameInfo.State.Transitioning) { if (CurrentState == KMGameInfo.State.Setup) { DemandBasedLoading.DisabledModsCount = 0; } if (CurrentState != KMGameInfo.State.Gameplay) { DemandBasedLoading.HandleTransitioning(); } } CurrentState = state; watcher.EnableRaisingEvents = state == KMGameInfo.State.Setup; if (state == KMGameInfo.State.Gameplay) { if (AdvantageousFeaturesEnabled) { LeaderboardController.DisableLeaderboards(); } TwitchPlaysActiveCache = TwitchPlaysActive; CurrentModeCache = CurrentMode; BombStatus.Instance.widgetsActivated = false; BombStatus.Instance.HUD.SetActive(settings.BombHUD); 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.Clear(); StartCoroutine(CheckForBombs()); 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 && CaseGeneratorSettingCache != settings.CaseGenerator) { if (settings.CaseGenerator) { tweaksMod.ModObjects.Add(TweaksCaseGeneratorCase); } else { tweaksMod.ModObjects.Remove(TweaksCaseGeneratorCase); } CaseGeneratorSettingCache = settings.CaseGenerator; } } StartCoroutine(Tips.ShowTip()); StartCoroutine(ModifyFreeplayDevice(true)); StartCoroutine(ModifyHoldables()); GetComponentInChildren <ModSelectorExtension>().FindAPI(); TweaksAPI.SetTPProperties(!TwitchPlaysActive); Patching.EnsurePatch("LogfileViewerHotkey", typeof(LogfileUploaderPatch)); GameplayState.BombSeedToUse = -1; UpdateSettingWarnings(); UpdateBombCreator(); } 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; } } }; }
// Use this for initialization void Start() { this.tweaks = Tweaks.Find(); this.timer_ = 0.0f; }
void IDTExtensibility2.OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom) { try { foreach (ITaskPane item in TaskPaneInstances) { try { item.OnDisconnection(); } catch (NetRuntimeSystem.Exception exception) { NetOffice.DebugConsole.Default.WriteException(exception); } } foreach (var item in TaskPanes) { try { if (null != item.Pane && !item.Pane.IsDisposed) { item.Pane.Dispose(); } } catch (NetRuntimeSystem.Exception exception) { NetOffice.DebugConsole.Default.WriteException(exception); } } try { if (null != TaskPaneFactory && false == TaskPaneFactory.IsDisposed) { TaskPaneFactory.Dispose(); } } catch (NetRuntimeSystem.Exception exception) { NetOffice.DebugConsole.Default.WriteException(exception); } try { Tweaks.DisposeTweaks(Factory, this, Type); RaiseOnDisconnection(RemoveMode, ref custom); Utils.Dispose(); } catch (NetRuntimeSystem.Exception exception) { Factory.Console.WriteException(exception); } try { if (!Application.IsDisposed) { Application.Dispose(); } } catch (NetRuntimeSystem.Exception exception) { NetOffice.DebugConsole.Default.WriteException(exception); } } catch (NetRuntimeSystem.Exception exception) { NetOffice.DebugConsole.Default.WriteException(exception); OnError(ErrorMethodKind.OnDisconnection, exception); } }
private static IEnumerator LoadModule(BombComponent fakeModule, BombInfo bombInfo) { // To preserve the order that the BombComponents were picked in, insert a null value and keep track of it's index to be replaced later. int componentIndex = bombInfo.Components.Count; bombInfo.Components.Add(null); modsLoading++; Time.timeScale = 0; yield return(null); totalModules = modsLoading; UpdateLoadingScreen(); yield return(null); string SteamID = fakeModule.gameObject.name.Replace("(Clone)", ""); string ModuleID = fakeModule.GetComponent <KMBombModule>()?.ModuleType ?? fakeModule.GetComponent <KMNeedyModule>()?.ModuleType; if (modLoading.ContainsKey(SteamID)) { yield return(new WaitUntil(() => !modLoading[SteamID])); } if (!manuallyLoadedMods.TryGetValue(SteamID, out Mod mod)) { var modPath = Path.Combine(modWorkshopPath, SteamID); if (!Directory.Exists(modPath)) { yield break; } modLoading[SteamID] = true; mod = Mod.LoadMod(modPath, Assets.Scripts.Mods.ModInfo.ModSourceEnum.Local); foreach (string fileName in mod.GetAssetBundlePaths()) { var bundleRequest = AssetBundle.LoadFromFileAsync(fileName); yield return(bundleRequest); var mainBundle = bundleRequest.assetBundle; if (mainBundle != null) { try { mod.LoadBundle(mainBundle); } catch (Exception ex) { Debug.LogErrorFormat("Load of mod \"{0}\" failed: \n{1}\n{2}", mod.ModID, ex.Message, ex.StackTrace); } loadedObjects[SteamID] = mainBundle.LoadAllAssets <UnityEngine.Object>(); mainBundle.Unload(false); } } mod.CallMethod("RemoveMissions"); mod.CallMethod("RemoveSoundOverrides"); manuallyLoadedMods[SteamID] = mod; loadedMods[modPath] = mod; modLoading[SteamID] = false; } loadOrder.Remove(SteamID); loadOrder.Add(SteamID); if (mod == null) { yield break; } List <string> moduleIDs = new List <string>(); BombComponent realModule = null; foreach (KMBombModule kmbombModule in mod.GetModObjects <KMBombModule>()) { string moduleType = kmbombModule.ModuleType; if (moduleType == ModuleID) { realModule = kmbombModule.GetComponent <BombComponent>(); } moduleIDs.Add(moduleType); } foreach (KMNeedyModule kmneedyModule in mod.GetModObjects <KMNeedyModule>()) { string moduleType = kmneedyModule.ModuleType; if (moduleType == ModuleID) { realModule = kmneedyModule.GetComponent <BombComponent>(); } moduleIDs.Add(moduleType); } if (realModule != null) { foreach (ModService original in mod.GetModObjects <ModService>()) { GameObject gameObject = UnityEngine.Object.Instantiate(original).gameObject; gameObject.transform.parent = ModManager.Instance.transform; mod.AddServiceObject(gameObject); } bombInfo.Components[componentIndex] = realModule.GetComponent <BombComponent>(); } else { Tweaks.Log($"Unable to get the real module for {ModuleID} ({SteamID}). IDs found: {moduleIDs.Select(id => $"\"{id}\"").Join(", ")}. This shouldn't happen, please contact the developer of Tweaks."); LeaderboardController.DisableLeaderboards(); bombInfo.Components[componentIndex] = fakeModule; } modsLoading--; UpdateLoadingScreen(); if (modsLoading == 0) { Time.timeScale = 1; } }
static IEnumerator GetModules() { var steamDirectory = SteamDirectory; var repositoryBackup = Path.Combine(Application.persistentDataPath, "RepositoryBackup.json"); UnityWebRequest request = UnityWebRequest.Get("https://ktane.timwi.de/json/raw"); yield return(request.SendWebRequest()); string repositoryJSON = null; if (request.isNetworkError) { Tweaks.Log("Unable to load the repository:", request.error); if (File.Exists(repositoryBackup)) { repositoryJSON = File.ReadAllText(repositoryBackup); } else { Tweaks.Log("Could not find a repository backup."); } } else { repositoryJSON = request.downloadHandler.text; } if (repositoryJSON == null) { Tweaks.Log("Could not get module information."); } else if (steamDirectory == null) { Tweaks.Log("Unable to find Steam!"); } else { // Save a backup of the repository File.WriteAllText(repositoryBackup, repositoryJSON); var disabledMods = ModSettingsManager.Instance.ModSettings.DisabledModPaths.ToList(); modWorkshopPath = Path.GetFullPath(new[] { steamDirectory, "steamapps", "workshop", "content", "341800" }.Aggregate(Path.Combine)); var fakeModuleParent = new GameObject("FakeModuleParent"); fakeModuleParent.transform.parent = Tweaks.Instance.transform; fakeModuleParent.SetActive(false); var loadedBombComponents = ModManager.Instance.GetValue <Dictionary <string, BombComponent> >("loadedBombComponents"); var json = JsonConvert.DeserializeObject <WebsiteJSON>(repositoryJSON); var cantLoad = new List <string>(); foreach (KtaneModule module in json.KtaneModules) { // Don't load anything that: // Doesn't have a Steam ID. // Isn't a module. // Is on the user's exclude list. if ( module.SteamID == null || !(module.Type == "Regular" || module.Type == "Needy") || Tweaks.settings.DemandBasedModsExcludeList.Any(name => module.Name.Like(name)) ) { continue; } var modPath = Path.Combine(modWorkshopPath, module.SteamID); if (!Directory.Exists(modPath)) { cantLoad.Add($"{module.ModuleID} ({module.SteamID})"); continue; } // Disable mods we are going to load on demand if (!disabledMods.Contains(modPath)) { disabledMods.Add(modPath); DisabledModsCount++; } if (loadedBombComponents.ContainsKey(module.ModuleID)) { continue; } GameObject fakeModule = new GameObject("FakeModule"); fakeModule.transform.parent = fakeModuleParent.transform; if (module.Type == "Regular") { var fakeBombComponent = fakeModule.AddComponent <ModBombComponent>(); var bombModule = fakeModule.AddComponent <KMBombModule>(); fakeBombComponent.SetValue("module", bombModule); fakeBombComponent.enabled = false; fakeBombComponent.ComponentType = ComponentTypeEnum.Mod; bombModule.ModuleType = module.ModuleID; bombModule.ModuleDisplayName = module.Name; } else { var fakeNeedyComponent = fakeModule.AddComponent <ModNeedyComponent>(); var needyModule = fakeModule.AddComponent <KMNeedyModule>(); fakeNeedyComponent.SetValue("module", needyModule); fakeNeedyComponent.enabled = false; fakeNeedyComponent.ComponentType = ComponentTypeEnum.NeedyMod; needyModule.ModuleType = module.ModuleID; needyModule.ModuleDisplayName = module.Name; } fakeModule.gameObject.name = module.SteamID; fakeModule.AddComponent <FakeModule>(); fakeModule.AddComponent <Selectable>(); fakeModule.AddComponent <ModSource>().ModName = "Tweaks"; loadedBombComponents[module.ModuleID] = fakeModule.GetComponent <BombComponent>(); fakedModules.Add(module.ModuleID); } if (cantLoad.Count > 0) { Tweaks.Log($"Can't load: {cantLoad.Join(", ")}".ChunkBy(250).Join("\n")); } ModSettingsManager.Instance.ModSettings.DisabledModPaths = disabledMods.ToArray(); ModSettingsManager.Instance.SaveModSettings(); } Time.timeScale = 1; }
IEnumerator GetModuleInformation(BombComponent bombComponent) { int moduleID = -1; KMBombModule bombModule = bombComponent.GetComponent <KMBombModule>(); string moduleType = bombModule != null ? bombModule.ModuleType : bombComponent.ComponentType.ToString(); displayNames[moduleType] = bombComponent.GetModuleDisplayName(); if (bombModule != null) { // Try to find a module ID from a field System.Reflection.FieldInfo idField = ReflectedTypes.GetModuleIDNumber(bombModule, out Component targetComponent); if (idField != null) { // Find the module ID from reflection float startTime = Time.time; yield return(new WaitUntil(() => { moduleID = (int)idField.GetValue(targetComponent); return moduleID != 0 || Time.time - startTime > 30; // Check to see if the field has been initialized with an ID or fail out after 30 seconds. })); } // From the object name. string prefix = bombModule.ModuleDisplayName + " #"; if (bombModule.gameObject.name.StartsWith(prefix) && !int.TryParse(bombModule.gameObject.name.Substring(prefix.Length), out moduleID)) { moduleID = -1; } } // From the logger property of vanilla components string loggerName = bombComponent.GetValue <object>("logger")?.GetValue <object>("Logger")?.GetValue <string>("Name"); if (loggerName != null && !int.TryParse(loggerName.Substring(loggerName.IndexOf('#') + 1), out moduleID)) { moduleID = -1; } // TODO: Handle logging implemented by Tweaks if (moduleID != -1) { if (!ids.ContainsKey(moduleType)) { ids[moduleType] = new List <int>(); } ids[moduleType].Add(moduleID); } else { Tweaks.Log(bombComponent.GetModuleDisplayName(), "has no module id."); } // Find anchor index int index = 0; foreach (BombFace face in Bomb.Faces) { foreach (Transform anchor in face.Anchors) { if ((anchor.position - bombComponent.transform.position).magnitude < 0.05) { modules[index] = moduleID != -1 ? $"{moduleType} {moduleID}" : $"{moduleType} -"; break; } index++; } } modulesUnactivated--; if (modulesUnactivated == 0) { string[] chunks = JsonConvert.SerializeObject(bombLogInfo).ChunkBy(250).ToArray(); Tweaks.Log("LFABombInfo", chunks.Length + "\n" + chunks.Join("\n")); } }
public void Start() { this.tweaks_ = Tweaks.Find(); Assert.AreEqual(this.StartPositions.Length, this.PlayerList.Length); this.players_on_track_ = new List<PlayerPosition>[this.PlayerList.Length]; for(int i=0; i<this.PlayerList.Length; ++i) { this.players_on_track_[i] = new List<PlayerPosition>(); } CallSetupOnAllPlayers (); }
private static IEnumerator InstantiateComponents(Bomb bomb) { yield return(new WaitUntil(() => modsLoading == 0)); var bombGenerator = SceneManager.Instance.GameplayState.GetValue <BombGenerator>("bombGenerator"); bombGenerator.SetValue("bomb", bomb); var validBombFaces = new List <BombFace>(bomb.Faces.Where(face => face.ComponentSpawnPoints.Count != 0)); bombGenerator.SetValue("validBombFaces", validBombFaces); List <KMBombInfo> knownBombInfos = new List <KMBombInfo>(); foreach (KMBombInfo item in UnityEngine.Object.FindObjectsOfType <KMBombInfo>()) { knownBombInfos.Add(item); } var bombInfo = allBombInfo[bomb]; var timerFace = bombInfo.TimerFace; var setting = bombInfo.Settings; bombInfo.EnableOriginal = true; bombGenerator.SetValue("rand", bombInfo.Rand); // Bring back the real Random object. UnityEngine.Random.InitState(bomb.Seed); // Loading AudioClips triggers RNG calls so we need to reset the RNG to before that happened. foreach (var bombComponent in bombInfo.Components.OrderByDescending(component => component.RequiresTimerVisibility)) { BombFace face = null; if (bombComponent.RequiresTimerVisibility && timerFace.ComponentSpawnPoints.Count != 0) { face = timerFace; } if (face == null && validBombFaces.Count != 0) { face = validBombFaces[bombInfo.Rand.Next(0, validBombFaces.Count)]; } if (face == null) { Tweaks.Log("No valid faces remain to instantiate:", bombComponent.name); continue; } bombGenerator.CallMethod("InstantiateComponent", face, bombComponent, setting); } while (validBombFaces.Count > 0) { bombGenerator.CallMethod("InstantiateComponent", validBombFaces[0], bombGenerator.emptyComponentPrefab, setting); } // To ensure that the widgets get placed in the right position, we need to temporarily revert the bomb's size. bomb.visualTransform.localScale = Vector3.one; WidgetGenerator generator = bombGenerator.GetComponent <WidgetGenerator>(); generator.SetValue("zones", bombInfo.WidgetZones); generator.GenerateWidgets(bomb.WidgetManager, setting.OptionalWidgetCount); bomb.visualTransform.localScale = new Vector3(bomb.Scale, bomb.Scale, bomb.Scale); bombInfo.Loaded = true; HookUpMultipleBombs(bomb, knownBombInfos); if (BombsLoaded) { SceneManager.Instance.GameplayState.Bombs.AddRange(allBombInfo.Keys); allBombInfo.Clear(); // This fixes the bomb not getting picked up correctly if clicked on before loading is finished. var holdable = KTInputManager.Instance.SelectableManager.GetCurrentFloatingHoldable(); if (holdable) { holdable.Defocus(false, false); } } // Solve any fake modules foreach (BombComponent component in bomb.BombComponents) { if (component.GetComponent <FakeModule>() != null) { component.IsSolved = true; component.Bomb.OnPass(component); } } }
void IDTExtensibility2.OnStartupComplete(ref Array custom) { Tweaks.ApplyTweaks(Factory, this, Type, "Outlook"); RaiseOnStartupComplete(ref custom); }
private static IEnumerator InstantiateComponents(Bomb bomb) { yield return(new WaitUntil(() => modsLoading == 0 && bombQueue.Count != 0 && bombQueue.Peek() == bomb)); var bombGenerator = SceneManager.Instance.GameplayState.GetValue <BombGenerator>("bombGenerator"); bombGenerator.SetValue("bomb", bomb); var logger = bombGenerator.GetValue <ILog>("logger"); // Enable logging again ((log4net.Repository.Hierarchy.Logger)logger.Logger).Level = null; var validBombFaces = new List <BombFace>(bomb.Faces.Where(face => face.ComponentSpawnPoints.Count != 0)); bombGenerator.SetValue("validBombFaces", validBombFaces); List <KMBombInfo> knownBombInfos = new List <KMBombInfo>(); foreach (KMBombInfo item in UnityEngine.Object.FindObjectsOfType <KMBombInfo>()) { knownBombInfos.Add(item); } var bombInfo = allBombInfo[bomb]; var timerFace = bombInfo.TimerFace; var setting = bombInfo.Settings; bombInfo.EnableOriginal = true; bombGenerator.SetValue("rand", bombInfo.Rand); // Bring back the real Random object. UnityEngine.Random.InitState(bomb.Seed); // Loading AudioClips triggers RNG calls so we need to reset the RNG to before that happened. // Emulate logging messages logger.InfoFormat("Generating bomb with seed {0}", bomb.Seed); logger.InfoFormat("Generator settings: {0}", setting.ToString()); foreach (var component in bombInfo.Components) { logger.InfoFormat("Selected {0} ({1})", Modes.GetModuleID(component), component); } var requiresTimer = bombInfo.Components.Where(component => component.RequiresTimerVisibility).Select(Modes.GetModuleID).ToArray(); var anyFace = bombInfo.Components.Where(component => !component.RequiresTimerVisibility).Select(Modes.GetModuleID).ToArray(); logger.DebugFormat("Bomb component list: RequiresTimerVisibility [{0}], AnyFace: [{1}]", string.Join(", ", requiresTimer), string.Join(", ", anyFace)); logger.DebugFormat("Instantiating RequiresTimerVisibility components on {0}", timerFace); // Spawn components bool loggedRemaining = false; foreach (var bombComponent in bombInfo.Components.OrderByDescending(component => component.RequiresTimerVisibility)) { BombFace face = null; if (bombComponent.RequiresTimerVisibility && timerFace.ComponentSpawnPoints.Count != 0) { face = timerFace; } else if (!loggedRemaining) { logger.Debug("Instantiating remaining components on any valid face."); loggedRemaining = true; } if (face == null && validBombFaces.Count != 0) { face = validBombFaces[bombInfo.Rand.Next(0, validBombFaces.Count)]; } if (face == null) { Tweaks.Log("No valid faces remain to instantiate:", bombComponent.name); continue; } bombGenerator.CallMethod("InstantiateComponent", face, bombComponent, setting); } logger.Debug("Filling remaining spaces with empty components."); while (validBombFaces.Count > 0) { bombGenerator.CallMethod("InstantiateComponent", validBombFaces[0], bombGenerator.emptyComponentPrefab, setting); } // We need to re-Init() the bomb face selectables so that the components get their correct X and Y positions for Gamepad support. foreach (Selectable selectable in bomb.Faces.Select(face => face.GetComponent <Selectable>())) { selectable.Init(); } logger.Debug("Generating Widgets"); // To ensure that the widgets get placed in the right position, we need to temporarily revert the bomb's size. bomb.visualTransform.localScale = Vector3.one; WidgetGenerator generator = bombGenerator.GetComponent <WidgetGenerator>(); generator.SetValue("zones", bombInfo.WidgetZones); generator.GenerateWidgets(bomb.WidgetManager, setting.OptionalWidgetCount); bomb.visualTransform.localScale = new Vector3(bomb.Scale, bomb.Scale, bomb.Scale); bombInfo.Loaded = true; HookUpMultipleBombs(bomb, knownBombInfos); bombQueue.Dequeue(); if (BombsLoaded) { SceneManager.Instance.GameplayState.Bombs.AddRange(allBombInfo.Keys); allBombInfo.Clear(); // This fixes the bomb not getting picked up correctly if clicked on before loading is finished. var holdable = KTInputManager.Instance.SelectableManager.GetCurrentFloatingHoldable(); if (holdable) { holdable.Defocus(false, false); } } // Solve any fake modules foreach (BombComponent component in bomb.BombComponents) { if (component.GetComponent <FakeModule>() != null) { component.IsSolved = true; component.Bomb.OnPass(component); } } }
void NetOffice.Tools.Native.IDTExtensibility2.OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom) { try { try { RaiseOnDisconnection(RemoveMode, ref custom); Tweaks.DisposeTweaks(Factory, this, Type); Utils.Dispose(); } catch (NetRuntimeSystem.Exception exception) { Factory.Console.WriteException(exception); } foreach (ITaskPane item in TaskPaneInstances) { try { item.OnDisconnection(); } catch (NetRuntimeSystem.Exception exception) { NetOffice.DebugConsole.Default.WriteException(exception); } } try { foreach (var item in OpenFormRegions) { try { IDisposable disposable = item as IDisposable; if (null != disposable) { disposable.Dispose(); } else { item.UnderlyingRegion.Dispose(); } } catch (NetRuntimeSystem.Exception exception) { NetOffice.DebugConsole.Default.WriteException(exception); } } OpenFormRegions.Clear(); } catch (NetRuntimeSystem.Exception exception) { NetOffice.DebugConsole.Default.WriteException(exception); } foreach (var item in TaskPanes) { try { if (null != item.Pane && !item.Pane.IsDisposed) { item.Pane.Dispose(); } } catch (NetRuntimeSystem.Exception exception) { NetOffice.DebugConsole.Default.WriteException(exception); } } try { if (null != TaskPaneFactory && false == TaskPaneFactory.IsDisposed) { TaskPaneFactory.Dispose(); } } catch (NetRuntimeSystem.Exception exception) { NetOffice.DebugConsole.Default.WriteException(exception); } try { if (null != RibbonUI) { RibbonUI.Dispose(); RibbonUI = null; } } catch (NetRuntimeSystem.Exception exception) { NetOffice.DebugConsole.Default.WriteException(exception); } try { if (!Application.IsDisposed) { Application.Dispose(); } } catch (NetRuntimeSystem.Exception exception) { NetOffice.DebugConsole.Default.WriteException(exception); } } catch (NetRuntimeSystem.Exception exception) { NetOffice.DebugConsole.Default.WriteException(exception); OnError(ErrorMethodKind.OnDisconnection, exception); } }
static void HandleCaseGeneration() { Tweaks.FixRNGSeed(); BombGenerator bombGenerator = Object.FindObjectOfType <BombGenerator>(); if (bombGenerator.BombPrefabOverride == null) // No point in doing anything if they aren't even going to use the ObjectPool. { ObjectPool prefabPool = bombGenerator.BombPrefabPool; // Generate a case parent if (CaseParent != null) { Object.Destroy(CaseParent); } // We have to parent the case to a GameObject that isn't active so it doesn't appear in the scene but itself is still active. CaseParent = new GameObject(); CaseParent.SetActive(false); // Override any KMGameCommands foreach (KMGameCommands gameCommands in Object.FindObjectsOfType <KMGameCommands>()) { var previousDelegate = gameCommands.OnCreateBomb; gameCommands.OnCreateBomb = (string missionId, KMGeneratorSetting generatorSettings, GameObject spawnTarget, string seed) => { HandleGeneratorSetting(ModMission.CreateGeneratorSettingsFromMod(generatorSettings), prefabPool); return(previousDelegate(missionId, generatorSettings, spawnTarget, seed)); }; } // This must happen regardless of even BetterCasePicker is enabled so that the game can't try to spawn the fake case. prefabPool.Objects = prefabPool.Objects.Where(gameobject => gameobject.name != "TweaksCaseGenerator").ToList(); if (!Tweaks.settings.BetterCasePicker && !Tweaks.CaseGeneratorSettingCache) { return; } // Try to figure out what mission we are going into Mission mission = null; if (!string.IsNullOrEmpty(GameplayState.MissionToLoad)) { if (GameplayState.MissionToLoad.Equals(FreeplayMissionGenerator.FREEPLAY_MISSION_ID)) { mission = FreeplayMissionGenerator.Generate(GameplayState.FreeplaySettings); } else if (GameplayState.MissionToLoad.Equals(ModMission.CUSTOM_MISSION_ID)) { mission = GameplayState.CustomMission; } else { mission = MissionManager.Instance.GetMission(GameplayState.MissionToLoad); } } if (mission == null) { Debug.LogError("[BetterCasePicker] Unable to find the current mission"); return; } HandleGeneratorSetting(mission.GeneratorSetting, prefabPool); } }
private void CompileToResponse(TemporaryDirectory td, TempFileCollection tfc, List <string> files, Stack <IIntermediateProject> partialCompletions, Dictionary <IIntermediateModule, List <string> > moduleFiles, out IIntermediateCompilerCommandLineModule module, out List <string> commandSequences, out string response) { module = (IIntermediateCompilerCommandLineModule)this.Module; commandSequences = new List <string>(); if (this.Project.OutputType == ProjectOutputType.ConsoleApplication || this.Project.OutputType == ProjectOutputType.WindowsApplication) { IMethodMember entryPoint = Project.EntryPoint; if (entryPoint != null && ((IDeclaredType)entryPoint.ParentTarget).Module != Project.RootModule) { IClassType entryPointCover = Project.Partials.AddNew().DefaultNameSpace.Classes.AddNew(Project.Classes.GetUniqueName("_cover")); entryPointCover.Attributes.AddNew(typeof(CompilerGeneratedAttribute)); entryPointCover.IsStatic = true; entryPointCover.AccessLevel = DeclarationAccessLevel.Internal; entryPointCover.Module = Project.RootModule; IMethodMember coverPoint = entryPointCover.Methods.AddNew(new TypedName(entryPoint.Name, entryPoint.ReturnType)); coverPoint.Attributes.AddNew(typeof(CompilerGeneratedAttribute)); foreach (IMethodParameterMember impm in entryPoint.Parameters.Values) { coverPoint.Parameters.AddNew(new TypedName(impm.Name, impm.ParameterType)); } coverPoint.Summary = "Entrypoint cover method, invokes the true entrypoint in a different module."; IMethodInvokeExpression imie = entryPoint.GetReference().Invoke(); foreach (IMethodParameterMember impm in entryPoint.Parameters.Values) { imie.ArgumentExpressions.Add(impm.GetReference()); } if (!(coverPoint.ReturnType.Equals(typeof(void).GetTypeReference()))) { coverPoint.Return(imie); } else { coverPoint.CallMethod(imie); } string entryFile = ProjectTranslator.WriteFile(this.Project, this.Translator, td, tfc, partialCompletions, entryPointCover, ".cs", " "); moduleFiles[Project.RootModule].Add(entryFile); files.Add(entryFile); commandSequences.Add(module.GetEntryPointCommand(coverPoint, this.Options)); this.Project.Partials.Remove((IIntermediateProject)entryPointCover.ParentTarget.ParentTarget); } else { commandSequences.Add(module.GetEntryPointCommand(entryPoint, this.Options)); } } List <string> moduleCommandLines = new List <string>(); foreach (IIntermediateModule iim in this.Project.Modules.Values) { string[] moduleFileNames = new string[moduleFiles[iim].Count + (iim == this.Project.RootModule ? this.Options.ExtraFiles.Count() : 0)]; for (int i = 0; i < moduleFiles[iim].Count; i++) { moduleFileNames[i] = moduleFiles[iim][i]; } if (iim == this.Project.RootModule) { int exC = this.Options.ExtraFiles.Count(); int exO = moduleFiles[iim].Count; int index = exO; foreach (var extraFile in this.Options.ExtraFiles) { var tempFile = td.Directories.GetTemporaryDirectory(iim.Name).Files.GetTemporaryFile(Path.GetFileName(extraFile)); tempFile.CloseStream(); File.Copy(extraFile, tempFile.FileName, true); moduleFileNames[index++] = tempFile.FileName; } } moduleCommandLines.AddRange(module.GetModuleCommand(iim, moduleFileNames, null, this.Options)); } bool allowPartials = this.Translator.Options.AllowPartials; this.Translator.Options.AllowPartials = false; ProjectDependencyReport pdr = new ProjectDependencyReport(this.Project, this.Translator.Options); pdr.Begin(); this.Translator.Options.AllowPartials = allowPartials; if (module.Supports(CompilerModuleSupportFlags.Optimization)) { commandSequences.Add(module.GetOptimizationCommand(this.Options.Optimize, this.Options)); } if (module.Supports(CompilerModuleSupportFlags.DebuggerSupport)) { commandSequences.Add(module.GetDebugCommand(this.Options.DebugSupport, this.Options)); } if (module.Supports(CompilerModuleSupportFlags.XMLDocumentation)) { commandSequences.Add(module.GetXMLDocumentationCommand(this.Options.GenerateXMLDocs, this.Options)); } commandSequences.AddRange(module.GetReferencesCommand(Tweaks.TranslateArray(pdr.CompiledAssemblyReferences.ToArray(), a => { return(a.Location); }), this.Options)); if (module.Supports(CompilerModuleSupportFlags.MultiFileAssemblies)) { commandSequences.AddRange(moduleCommandLines.ToArray()); } else { commandSequences.Add(module.GetOutputCommand(this.Options.Target, this.Options)); commandSequences.AddRange(module.GetSourcesCommand(files.ToArray(), this.Options)); } response = null; if (module.Supports(CompilerModuleSupportFlags.ResponseFile)) { response = tfc.AddExtension("response"); StreamWriter responseWriter = new StreamWriter(new FileStream(response, FileMode.Create)); //string[] lines = fullCommand.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (string s in commandSequences) { responseWriter.WriteLine(s); } responseWriter.Flush(); responseWriter.Close(); } }