/// <summary> /// Try to categorize the specified vessel based on any VesselCategorizerModule /// it contains. Returns true if the vessel type was set, false if it was left alone /// because either there's no VesselCategorizerModule, or else because it was /// set to "default". /// </summary> /// <param name="vessel"></param> /// <returns></returns> public static bool TryCategorize(Vessel vessel) { if (vessel == null) { return(false); } if (vessel.Parts == null) { return(false); } int vesselTypeSelection = -1; List <ModuleVesselCategorizer> toRemove = new List <ModuleVesselCategorizer>(); for (int partIndex = 0; partIndex < vessel.Parts.Count; ++partIndex) { Part part = vessel.Parts[partIndex]; toRemove.Clear(); for (int moduleIndex = 0; moduleIndex < part.Modules.Count; ++moduleIndex) { ModuleVesselCategorizer module = part.Modules[moduleIndex] as ModuleVesselCategorizer; if (module == null) { continue; } if (vesselTypeSelection < 0) { vesselTypeSelection = module.vesselTypeSelection; } toRemove.Add(module); } for (int i = 0; i < toRemove.Count; ++i) { // We remove all the modules from the ship because they've served their purpose. // We just extract the selected vessel type, once part.Modules.Remove(toRemove[i]); } } // for each part on the vessel if (vesselTypeSelection < 1) { return(false); // nothing found, or else selection was "default" } int typeIndex = vesselTypeSelection - 1; if (typeIndex >= _vesselTypes.Length) { return(false); // wtf? should never happen } VesselType assignedType = _vesselTypes[typeIndex]; Logging.Log("Setting type of " + vessel.vesselName + " to " + assignedType + " (manual user selection in editor)"); vessel.vesselType = assignedType; return(true); }
/// <summary> /// Finds the first ModuleVesselCategorizer on the part, or null if none. /// </summary> /// <param name="part"></param> /// <returns></returns> public static ModuleVesselCategorizer FindFirst(Part part) { if (part == null) { return(null); } for (int i = 0; i < part.Modules.Count; ++i) { ModuleVesselCategorizer module = part.Modules[i] as ModuleVesselCategorizer; if (module != null) { return(module); } } return(null); }
/// <summary> /// Here when a new vessel is launched to the launchpad. This is where we set the vessel type. /// </summary> /// <param name="vessel"></param> private void OnVesselLaunch(Vessel vessel) { // First, see if the user manually assigned a vessel type in the editor. if (ModuleVesselCategorizer.TryCategorize(vessel)) { return; } // Nope. Well, can we assign a vessel type based on the name? if (NameCategorizer.TryCategorize(vessel)) { return; } // Still nope. Okay, all out of ideas, we'll just leave it alone. Logging.Log("No changes made to vessel type for " + vessel.vesselName); }
/// <summary> /// Scan the provided part and all its children recursively, looking for any of them that have /// a ModuleVesselCategorizer. Add any found modules to the list. /// </summary> /// <param name="root"></param> /// <param name="toInitialize"></param> private static void CollectToInitializerList(Part root, List <ModuleVesselCategorizer> toInitialize) { if (root == null) { return; } ModuleVesselCategorizer module = ModuleVesselCategorizer.FindFirst(root); if (module != null) { toInitialize.Add(module); } if (root.children == null) { return; } for (int i = 0; i < root.children.Count; ++i) { CollectToInitializerList(root.children[i], toInitialize); } }
/// <summary> /// Initialize all modules in the supplied list so that they have the same /// selection value as what's already on the current ship construct, if there is one. /// </summary> /// <param name="toInitialize"></param> private static void Initialize(List <ModuleVesselCategorizer> toInitialize) { if (toInitialize.Count < 1) { return; // nothing to do } try { ModuleVesselCategorizer existing = FindFirstNotInList(toInitialize); if (existing == null) { return; } for (int i = 0; i < toInitialize.Count; ++i) { toInitialize[i].vesselTypeSelection = existing.vesselTypeSelection; } } finally { toInitialize.Clear(); } }
/// <summary> /// Finds the first ModuleVesselCategorizer on the current ship construct, aside /// from any module in the supplied list. Returns that module, or null if none exists. /// </summary> /// <param name="excluded"></param> /// <returns></returns> private static ModuleVesselCategorizer FindFirstNotInList(List <ModuleVesselCategorizer> excluded) { ShipConstruct ship = CurrentShipConstruct; if (ship == null) { return(null); } for (int i = 0; i < ship.Parts.Count; ++i) { Part part = ship.Parts[i]; ModuleVesselCategorizer module = ModuleVesselCategorizer.FindFirst(part); if (module == null) { continue; } if (excluded.Contains(module)) { continue; } return(module); } return(null); // nope, there isn't one }
/// <summary> /// Here when the value of vesselTypeSelection changes. It updates all /// the other VesselCategorizerModules on the ship to have the same value /// as itself. /// </summary> /// <param name="field"></param> /// <param name="value"></param> private void OnSelectionChanged(BaseField field, object value) { if (triggerIsSuppressed) { return; } ShipConstruct construct = EditorCategorization.CurrentShipConstruct; if (construct == null) { return; } for (int i = 0; i < construct.Count; ++i) { Part part = construct.parts[i]; if (part == null) { continue; } for (int j = 0; j < part.Modules.Count; ++j) { ModuleVesselCategorizer module = part.Modules[j] as ModuleVesselCategorizer; if (module == null) { continue; } if (ReferenceEquals(module, this)) { continue; } module.triggerIsSuppressed = true; module.vesselTypeSelection = vesselTypeSelection; module.triggerIsSuppressed = false; } } }