private IEnumerator Setup() { // Find the Mystery Module Service and obtain the list of compatibilities var mmService = FindObjectOfType <MysteryModuleService>(); if (mmService == null) { Debug.LogFormat(@"[Mystery Module #{0}] Catastrophic problem: Mystery Module Service is not present.", moduleId); goto mustAutoSolve; } yield return(new WaitUntil(() => mmService.SettingsLoaded)); var offendingModule = Bomb.GetSolvableModuleIDs().FirstOrDefault(n => mmService.MustAutoSolve(n)); if (offendingModule != null) { Debug.LogFormat(@"[Mystery Module #{0}] The module {1} ruins the mood! Green button can be pressed to solve this module.", moduleId, offendingModule); goto mustAutoSolve; } var serialNumber = Bomb.GetSerialNumber(); remainingCandidatesInfo inf; List <object> organizationModules = new List <object>(); if (!_infos.ContainsKey(serialNumber)) { inf = new remainingCandidatesInfo(); _infos[serialNumber] = inf; for (int i = 0; i < transform.parent.childCount; i++) { var module = transform.parent.GetChild(i).gameObject.GetComponent <KMBombModule>(); if (module == null) { continue; } if (!mmService.MustNotBeHidden(module.ModuleType)) { inf.RemainingCandidateMystifiables.Add(module); } if (!mmService.MustNotBeKey(module.ModuleType)) { inf.RemainingCandidateKeys.Add(module); } object orgMod; if (module.ModuleType == "organizationModule" && (orgMod = module.GetComponent("OrganizationScript")) != null) { organizationModules.Add(orgMod); } } } else { inf = _infos[serialNumber]; } var mystifiableCandidates = inf.RemainingCandidateMystifiables.Where(m => { // We need to make sure that Mystery Modules do not hide themselves in a cycle. // This code relies on the fact that we haven’t chosen a mystified module yet (mystsifiedModule for us is null). MysteryModuleScript scr; var my = m; while ((scr = my.GetComponent <MysteryModuleScript>()) != null && scr.mystifiedModule != null) { my = scr.mystifiedModule; } return(my != Module); }).ToArray(); if (mystifiableCandidates.Length == 0) { Debug.LogFormat(@"[Mystery Module #{0}] No possible candidate found to mystify - Green button can be pressed to solve this module.", moduleId); goto mustAutoSolve; } mystifiedModule = mystifiableCandidates[Random.Range(0, mystifiableCandidates.Length)]; inf.RemainingCandidateMystifiables.Remove(mystifiedModule); inf.RemainingCandidateKeys.Remove(mystifiedModule); // A mystified module cannot be a key anymore (for this or any other Mystery Module) if (inf.RemainingCandidateKeys.Count == 0) { Debug.LogFormat(@"[Mystery Module #{0}] No possible candidates for using as a key found - Green button can be pressed to solve this module.", moduleId); goto mustAutoSolve; } // Select a number of key modules keyModules = inf.RemainingCandidateKeys.ToList().Shuffle() .Take(Random.Range(1, Mathf.Max(2, inf.RemainingCandidateKeys.Count / (Bomb.GetSolvableModuleIDs().Count(m => m == Module.ModuleType) + 1)))) .ToList(); // These key modules can no longer be mystified by any other Mystery Module foreach (var km in keyModules) { inf.RemainingCandidateMystifiables.Remove(km); } Debug.LogFormat(@"[Mystery Module #{0}] Keys are: {1}, mystified module is: {2}", moduleId, keyModules.Select(km => km.ModuleDisplayName).Join(", "), mystifiedModule.ModuleDisplayName); Cover.SetActive(true); var mysPos = mystifiedModule.transform.localPosition; Cover.transform.parent = mystifiedModule.transform.parent; var scale = new Vector3(.95f, .95f, .95f); Cover.transform.localScale = scale; Cover.transform.rotation = mystifiedModule.transform.rotation; if (Cover.transform.rotation == new Quaternion(0f, 0f, 1f, 0f)) { Cover.transform.localPosition = new Vector3(mysPos.x, mysPos.y - 0.02f, mysPos.z); } else { Cover.transform.localPosition = new Vector3(mysPos.x, mysPos.y + 0.02f, mysPos.z); } Debug.LogFormat(@"[Mystery Module #{0}] Rotation: {1}", moduleId, Cover.transform.rotation); yield return(null); Cover.transform.parent = transform.parent; SetKey(); StartCoroutine(checkSolves()); mystifyScale = mystifiedModule.transform.localScale; mystifiedModule.transform.localScale = new Vector3(0, 0, 0); foreach (var org in organizationModules) { var mth = org.GetType().GetMethod("MysteryModuleNotification", BindingFlags.Public | BindingFlags.Instance); Debug.LogFormat(@"<Mystery Module #{0}> Notifying Organization: {1}", moduleId, mth != null); if (mth != null && mth.GetParameters().Select(p => p.ParameterType).SequenceEqual(new[] { typeof(List <string>), typeof(string) })) { Debug.LogFormat(@"[Mystery Module #{0}] Notifying Organization", moduleId); mth.Invoke(org, new object[] { keyModules.Select(k => k.ModuleDisplayName).ToList(), mystifiedModule.ModuleDisplayName }); } } yield break; mustAutoSolve: nextStage = true; SetLED(0, 255, 0); setScreen("Free solve :D", 0, 255, 0); failsolve = true; StopAllCoroutines(); }
private IEnumerator Setup() { yield return(null); // Find the Mystery Module Service and obtain the list of compatibilities var mmService = FindObjectOfType <MysteryModuleService>(); if (mmService == null) { Debug.LogFormat(@"[Mystery Module #{0}] Catastrophic problem: Mystery Module Service is not present."); goto mustAutoSolve; } var offendingModule = Bomb.GetSolvableModuleIDs().FirstOrDefault(n => mmService.MustAutoSolve(n)); if (offendingModule != null) { Debug.LogFormat(@"[Mystery Module #{0}] The module {1} ruins the mood! Green button can be pressed to solve this module.", moduleId, offendingModule); goto mustAutoSolve; } var serialNumber = Bomb.GetSerialNumber(); remainingCandidatesInfo inf; if (!_infos.ContainsKey(serialNumber)) { inf = new remainingCandidatesInfo(); _infos[serialNumber] = inf; for (int i = 0; i < transform.parent.childCount; i++) { var module = transform.parent.GetChild(i).gameObject.GetComponent <KMBombModule>(); if (module == null) { continue; } if (!mmService.MustNotBeHidden(module.ModuleType) || !mmService.ShouldNotBeHidden(module.ModuleType)) { inf.RemainingCandidateMystifiables.Add(module); } if (!mmService.MustNotBeKey(module.ModuleType)) { inf.RemainingCandidateKeys.Add(module); } } } else { inf = _infos[serialNumber]; } var mystifiableCandidates = inf.RemainingCandidateMystifiables.Where(m => { // We need to make sure that Mystery Modules do not hide themselves in a cycle. // This code relies on the fact that we haven’t chosen a mystified module yet (mystsifiedModule for us is null). MysteryModuleScript scr; var my = m; while ((scr = my.GetComponent <MysteryModuleScript>()) != null && scr.mystifiedModule != null) { my = scr.mystifiedModule; } return(my != Module); }).ToArray(); if (mystifiableCandidates.Length == 0) { Debug.LogFormat(@"[Mystery Module #{0}] No possible candidate found to mystify - Green button can be pressed to solve this module.", moduleId); goto mustAutoSolve; } mystifiedModule = mystifiableCandidates[Random.Range(0, mystifiableCandidates.Length)]; inf.RemainingCandidateMystifiables.Remove(mystifiedModule); inf.RemainingCandidateKeys.Remove(mystifiedModule); // A mystified module cannot be a key anymore (for this or any other Mystery Module) if (inf.RemainingCandidateKeys.Count == 0) { Debug.LogFormat(@"[Mystery Module #{0}] No possible candidates for using as a key found - Green button can be pressed to solve this module.", moduleId); goto mustAutoSolve; } // Select a number of key modules keyModules = inf.RemainingCandidateKeys.ToList().Shuffle() .Take(Random.Range(1, Mathf.Max(2, inf.RemainingCandidateKeys.Count / (Bomb.GetSolvableModuleIDs().Count(m => m == Module.ModuleType) + 1)))) .ToList(); // These key modules can no longer be mystified by any other Mystery Module foreach (var km in keyModules) { inf.RemainingCandidateMystifiables.Remove(km); } Debug.LogFormat(@"[Mystery Module #{0}] Keys are: {1}, mystified module is: {2}", moduleId, keyModules.Select(km => km.ModuleDisplayName).Join(", "), mystifiedModule.ModuleDisplayName); var maxBounds = GetMaxBounds(mystifiedModule.gameObject); var coverBounds = GetMaxBounds(Cover); Cover.SetActive(true); Cover.transform.position = maxBounds.center; Cover.transform.parent = mystifiedModule.gameObject.transform; var scale = new Vector3(coverBounds.size.x / maxBounds.size.x, coverBounds.size.y / maxBounds.size.y, coverBounds.size.z / maxBounds.size.z); Cover.transform.localScale = scale; Cover.transform.rotation = mystifiedModule.transform.rotation; yield return(null); Cover.transform.parent = transform.parent; SetKey(); StartCoroutine(checkSolves()); mystifyScale = mystifiedModule.transform.localScale; mystifiedModule.transform.localScale = new Vector3(0, 0, 0); yield break; mustAutoSolve: nextStage = true; SetLED(0, 255, 0); setScreen("Free solve :D", 0, 255, 0); failsolve = true; StopAllCoroutines(); }