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); } }
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")); } }