private void Activate() { bool isEnabled = module.isEnabled; module.Load(dataNode); module.isEnabled = isEnabled; module.Events.Send("ModuleDataChanged", moduleDataChangedEventDetails); }
protected void runCompletionHandler(string experimentID, float chanceOfSuccess, float resultRoll) { if (nodeCompletionHandler == null) { return; } try { PartModule moduleHandler = this.part.AddModule(nodeCompletionHandler.GetValue("name")); moduleHandler.Load(nodeCompletionHandler); if (moduleHandler is IWBIExperimentResults) { IWBIExperimentResults resultsHandler = (IWBIExperimentResults)moduleHandler; resultsHandler.ExperimentRequirementsMet(experimentID, chanceOfSuccess, resultRoll); } this.part.RemoveModule(moduleHandler); } catch (Exception ex) { Debug.Log("[WBIModuleScienceExperiment] error while trying to run experiment completion handler: " + ex.ToString()); } }
//to call only on partprefab, as it create the partinfo public static PartModule createModule(Part part, ConfigNode nodeToCreate, bool withModuleInfo = true) { string moduleName = nodeToCreate.GetValue("name"); if (moduleName == null) { return(null); } PartModule newMod = part.AddModule(moduleName); if (Awaken(newMod)) { // uses reflection to find and call the PartModule.Awake() private method newMod.Load(nodeToCreate); //add info if (withModuleInfo && newMod.GetInfo().Length > 0) { //create AvailablePart.ModuleInfo info = new AvailablePart.ModuleInfo(); info.moduleName = newMod.moduleName.Replace("Module", ""); info.info = newMod.GetInfo(); //add part.partInfo.moduleInfos.Add(info); //sort info part.partInfo.moduleInfos.Sort((o1, o2) => o1.moduleName.CompareTo(o2.moduleName)); } return(newMod); } else { //Debug.log("create a module done & awake KO "); return(null); } }
private void addModuleFromConfig(Part evaPart, ConfigNode evaModuleNode) { string moduleName; if (evaModuleNode.TryGetValue("name", out moduleName)) { /*if (evaPart.GetComponents<PartModule>().Any(m => m.GetType().Name == moduleName)) * { * this.LogWarning("Skipping module {0}: already present in kerbalEVA", moduleName); * return; * }*/ Type moduleClass = AssemblyLoader.GetClassByName(typeof(PartModule), moduleName); if (moduleClass == null) { this.LogWarning("Skipping module {0}: class not found in loaded assemblies.", moduleName); return; } try { PartModule evaModule = evaPart.gameObject.AddComponent(moduleClass) as PartModule; var awakeMethod = typeof(PartModule).GetMethod("Awake", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance ); awakeMethod.Invoke(evaModule, new object[] {}); evaModule.Load(evaModuleNode); } catch (Exception ex) { this.LogError("Handled exception {0} while adding modules to {1}.", ex.GetType().Name, evaPart); #if DEBUG Debug.LogException(ex); #endif } if (evaPart.GetComponents <PartModule>().Any(m => m.GetType().Name == moduleName)) { this.Log("Added module {0} to {1}.", moduleName, evaPart); } else { this.LogWarning("Failed to add {0} to {1}.", moduleName, evaPart); } } else { this.LogWarning("Skipping malformed EVA_MODULE node: missing 'name' field."); return; } }
// add a module to an EVA kerbal public static void AddModuleToEVA(string module_name, ConfigNode module_node = null) { var eva_parts = PartLoader.LoadedPartsList.FindAll(k => k.name == "kerbalEVA" || k.name == "kerbalEVAfemale"); foreach (AvailablePart p in eva_parts) { Type type = AssemblyLoader.GetClassByName(typeof(PartModule), module_name); PartModule m = p.partPrefab.gameObject.AddComponent(type) as PartModule; if (module_node != null) m.Load(module_node); } }
// Method to ensure that all parts which have a crewcapacity >0 have a CLSModule attached to it. private void AddModuleToParts() { IEnumerator <AvailablePart> parts = PartLoader.LoadedPartsList.Where(p => p.partPrefab != null && p.partPrefab.CrewCapacity > 0).GetEnumerator(); while (parts.MoveNext()) { if (parts.Current == null) { continue; } try { if (parts.Current.name.Contains("kerbalEVA")) { // Debug.Log("No CLS required for KerbalEVA!"); } else { //Debug.Log($"Adding ConnectedLivingSpace Support to {part.name}/{prefabPart.partInfo.title}"); if (!parts.Current.partPrefab.Modules.Contains("ModuleConnectedLivingSpace")) { //Debug.Log("The ModuleConnectedLivingSpace is missing!"); ConfigNode node = new ConfigNode("MODULE"); node.AddValue("name", "ModuleConnectedLivingSpace"); { // This block is required as calling AddModule and passing in the node throws an exception if Awake has not been called. PartModule pm = parts.Current.partPrefab.AddModule("ModuleConnectedLivingSpace"); if (Awaken(pm)) { pm.Load(node); } } } else { // Debug.Log("The ModuleConnectedLivingSpace is already there."); } } } catch (Exception ex) { Debug.LogException(ex); } } parts.Dispose(); }
public PartModule createModule(ConfigNode nodeToCreate) { string moduleName = nodeToCreate.GetValue("name"); if (moduleName == null) { return(null); } PartModule newMod = part.AddModule(moduleName); MethodInfo awakeMethod = typeof(PartModule).GetMethod("Awake", BindingFlags.Instance | BindingFlags.NonPublic); awakeMethod.Invoke(newMod, new object[] { }); // uses reflection to find and call the PartModule.Awake() private method newMod.Load(nodeToCreate); return(newMod); }
public static void ModifyPart(Part part, ConfigNode node) { part.Fields.Load(node); //Step 2A: clear the old Resources part.Resources.list.Clear(); //Step 2B: load the new Resources foreach (ConfigNode rNode in node.GetNodes("RESOURCE")) { part.AddResource(rNode); } //Step 3A: clear the old Modules while (part.Modules.Count > 0) { part.RemoveModule(part.Modules [0]); } //Step 3B: load the new Modules foreach (ConfigNode mNode in node.GetNodes("MODULE")) { PartModule module = part.AddModule(mNode.GetValue("name")); if (module) { // really? REALLY? It appears the only way to make this work, is to molest KSP's privates. if (Awaken(module)) // uses reflection to find and call the PartModule.Awake() private method { module.Load(mNode); } else { print("Awaken failed for new module."); } if (module.part == null) { print("new module has null part."); } else { #if DEBUG print("Created module for " + module.part.name); #endif } } } }
// Method to ensure that all parts which have a crewcapacity >0 have a CLSModule attached to it. private void AddModuleToParts() { IEnumerable <AvailablePart> parts = PartLoader.LoadedPartsList.Where(p => p.partPrefab != null && p.partPrefab.CrewCapacity > 0); foreach (AvailablePart part in parts) { try { if (part.name.Equals("kerbalEVA")) { // Debug.Log("No CLS required for KerbalEVA!"); } else { Part prefabPart = part.partPrefab; //Debug.Log("Adding ConnectedLivingSpace Support to " + part.name + "/" + prefabPart.partInfo.title); if (!prefabPart.Modules.Contains("ModuleConnectedLivingSpace")) { //Debug.Log("The ModuleConnectedLivingSpace is missing!"); ConfigNode node = new ConfigNode("MODULE"); node.AddValue("name", "ModuleConnectedLivingSpace"); { // This block is required as calling AddModule and passing in the node throws an exception if Awake has not been called. The method Awaken uses reflection to call then private method Awake. See http://forum.kerbalspaceprogram.com/threads/27851 for more information. PartModule pm = prefabPart.AddModule("ModuleConnectedLivingSpace"); if (Awaken(pm)) { pm.Load(node); } } } else { // Debug.Log("The ModuleConnectedLivingSpace is already there."); } } } catch (Exception ex) { Debug.LogException(ex); } } }
/// <summary> /// Converts the InventoryPart into a Part using the stored modules /// </summary> /// <returns></returns> public Part ToPart() { //Part retPart = new Part(); AvailablePart aPart = Utils.AvailablePartFromName(Name); Part retPart = aPart.partPrefab; //set the modules to the ones we've saved if (retPart.Modules?.Count > 0) { foreach (ConfigNode saved in savedModules) { //look for this module on the partInfo and replace it string moduleName = saved.GetValue("name"); if (retPart.Modules.Contains(moduleName)) { PartModule correspondingModule = retPart.Modules[moduleName]; correspondingModule.Load(saved); } } } //foreach (PartModule mod in retPart.Modules) //{ // foreach (string trackedModuleName in ScrapYard.Instance.Settings.TrackedModules) // { // if (mod.moduleName.ToUpper().Contains(trackedModuleName)) // { // //replace the module with the version we've saved // ConfigNode savedModule = savedModules.FirstOrDefault(c => c.GetValue("name").ToUpper().Contains(trackedModuleName)); // if (savedModule != null) // { // mod.Load(savedModule); // } // } // } //} return(retPart); }
// Method to add Docking Hatches to all parts that have Docking Nodes private void AddHatchModuleToPartPrefabs() { IEnumerable <AvailablePart> parts = PartLoader.LoadedPartsList.Where(p => p.partPrefab != null); foreach (AvailablePart part in parts) { Part partPrefab = part.partPrefab; // If the part does not have any modules set up then move to the next part if (null == partPrefab.Modules) { continue; } List <ModuleDockingNode> listDockNodes = new List <ModuleDockingNode>(); List <ModuleDockingHatch> listDockHatches = new List <ModuleDockingHatch>(); // Build a temporary list of docking nodes to consider. This is necassery can we can not add hatch modules to the modules list while we are enumerating the very same list! foreach (ModuleDockingNode dockNode in partPrefab.Modules.OfType <ModuleDockingNode>()) { listDockNodes.Add(dockNode); } foreach (ModuleDockingHatch dockHatch in partPrefab.Modules.OfType <ModuleDockingHatch>()) { listDockHatches.Add(dockHatch); } foreach (ModuleDockingNode dockNode in listDockNodes) { // Does this docking node have a corresponding hatch? ModuleDockingHatch hatch = null; foreach (ModuleDockingHatch h in listDockHatches) { if (h.IsRelatedDockingNode(dockNode)) { hatch = h; break; } } if (null == hatch) { // There is no corresponding hatch - add one. ConfigNode node = new ConfigNode("MODULE"); node.AddValue("name", "ModuleDockingHatch"); if (dockNode.referenceAttachNode != string.Empty) { Debug.Log("Adding ModuleDockingHatch to part " + part.title + " and the docking node that uses attachNode " + dockNode.referenceAttachNode); node.AddValue("docNodeAttachmentNodeName", dockNode.referenceAttachNode); } else { if (dockNode.nodeTransformName != string.Empty) { Debug.Log("Adding ModuleDockingHatch to part " + part.title + " and the docking node that uses transform " + dockNode.nodeTransformName); node.AddValue("docNodeTransformName", dockNode.nodeTransformName); } } { // This block is required as calling AddModule and passing in the node throws an exception if Awake has not been called. The method Awaken uses reflection to call then private method Awake. See http://forum.kerbalspaceprogram.com/threads/27851 for more information. PartModule pm = partPrefab.AddModule("ModuleDockingHatch"); if (Awaken(pm)) { Debug.Log("Loading the ModuleDockingHatch config"); pm.Load(node); } else { Debug.LogWarning("Failed to call Awaken so the config has not been loaded."); } } } } } }
public static void ModifyPart(AvailablePart partData, ConfigNode node) { //Step 1: load the Fields partData.partPrefab.Fields.Load(node); //Step 2A: clear the old Resources partData.partPrefab.Resources.list.Clear(); partData.resourceInfo = ""; //Step 2B: load the new Resources foreach (ConfigNode rNode in node.GetNodes("RESOURCE")) { PartResource resource = partData.partPrefab.AddResource(rNode); if (partData.resourceInfo.Length > 0) { partData.resourceInfo += "\n"; } partData.resourceInfo += resource.GetInfo(); } if (partData.resourceInfo.Length > 0) { partData.resourceInfo += "\nDry Mass: " + partData.partPrefab.mass.ToString("F3"); } //Step 3A: clear the old Modules while (partData.partPrefab.Modules.Count > 0) { partData.partPrefab.RemoveModule(partData.partPrefab.Modules [0]); } partData.moduleInfo = ""; //Step 3B: load the new Modules foreach (ConfigNode mNode in node.GetNodes("MODULE")) { PartModule module = partData.partPrefab.AddModule(mNode.GetValue("name")); if (module) { // really? REALLY? It appears the only way to make this work, is to molest KSP's privates. if (Awaken(module)) // uses reflection to find and call the PartModule.Awake() private method { module.Load(mNode); } else { print("Awaken failed for new module."); } if (module.part == null) { print("new module has null part."); } else { #if DEBUG print("Created module for " + module.part.name); #endif } } if (partData.moduleInfo.Length > 0) { partData.moduleInfo += "\n"; } partData.moduleInfo += module.GetInfo(); } }
private void Activate() => module.Load(dataNode);
private void InstallMode(ModuleSTPModularCorridor.ModeConfig m, bool isLoading = false) { ConfigNode conf = m.config; int idx = m.path.LastIndexOf('/'); string modelPath = m.path.Substring(0, idx) + "/" + conf.GetValue("model"); Debug.Log("[STB]: Loading: " + conf.GetValue("modeName") + " mode."); ConfigNode[] array = m.inRes; for (int j = 0; j < array.Length; j++) { ConfigNode i = array[j]; if (MBToolbox.AmountAvailable(i.GetValue("name"), FlightGlobals.ActiveVessel.rootPart) < System.Convert.ToDouble(i.GetValue("amount"))) { ScreenMessages.PostScreenMessage("Not enough " + i.GetValue("name"), 5f); return; } MBToolbox.RequestResource(i.GetValue("name"), System.Convert.ToDouble(i.GetValue("amount")), FlightGlobals.ActiveVessel.rootPart); } if (this.installedModule.hasInit() && !isLoading) { Debug.Log("[STB]: Reseting modules..."); if (this.installedModule.moduleconfs.Length != 0) { System.Collections.Generic.List <PartModule> pmToRemoveList = new System.Collections.Generic.List <PartModule>(); using (var enumerator = base.part.Modules.GetEnumerator()) { while (enumerator.MoveNext()) { PartModule pm = (PartModule)enumerator.Current; array = this.installedModule.moduleconfs; for (int j = 0; j < array.Length; j++) { ConfigNode i = array[j]; if (i.GetValue("name") == pm.moduleName) { pmToRemoveList.Add(pm); } } } } foreach (PartModule pm in pmToRemoveList) { base.part.RemoveModule(pm); Debug.Log("[STB]: Removing: " + pm.moduleName + " module."); } } Debug.Log("[STB]: Reseting resources..."); foreach (PartResource r in base.part.Resources) { array = this.installedModule.resconfs; for (int j = 0; j < array.Length; j++) { ConfigNode i = array[j]; if (i.GetValue("name") == r.resourceName) { ConfigNode node = i.CreateCopy(); node.SetValue("name", r.resourceName, false); node.SetValue("amount", "0", false); node.SetValue("maxAmount", "0", false); base.part.SetResource(node); Debug.Log("[STB]: Reseting " + r.resourceName); } } } Debug.Log("[STB]: Reseting model..."); if (this.currModel != null) { this.currModel.SetActive(false); } } if (m.isDepsOk) { Debug.Log("[STB]: Adding modules..."); array = m.moduleconfs; for (int j = 0; j < array.Length; j++) { ConfigNode i = array[j]; PartModule pm = base.part.AddModule(i.GetValue("name")); pm.OnAwake(); pm.OnInitialize(); pm.Load(i); pm.OnStart(PartModule.StartState.Landed); Debug.Log(i.GetValue("name") + " is being added from: " + i.name); } } if (!isLoading) { Debug.Log("[STB]: Adding resources..."); array = m.resconfs; for (int j = 0; j < array.Length; j++) { ConfigNode i = array[j]; if (i.GetValue("amount") != "0") { i.SetValue("amount", "0", false); } base.part.SetResource(i); Debug.Log(i.GetValue("name") + " " + i.name + " is being added"); } } Debug.Log("[STB]: Adding model..."); if (GameDatabase.Instance.ExistsModel(modelPath)) { GameObject go = GameDatabase.Instance.GetModel(modelPath); go.SetActive(true); go.layer = 15; go.name = conf.GetValue("modeName") + go.GetInstanceID(); go.transform.position = base.part.partTransform.position; go.transform.rotation = base.part.partTransform.rotation; go.transform.parent = base.part.partTransform; this.currModel = go; } else { Debug.Log("[STB] says: " + modelPath + " is not found!"); } this.installedModule = m; this.currModeName = conf.GetValue("modeName"); Debug.Log("[STB]: Installing done!"); }
private void Activate() { module.Load(dataNode); module.Events.Send("ModuleDataChanged", moduleDataChangedEventDetails); }
//called only in the prefab public override void Upgrade(List <string> allTechName) { //Debug.log("[MUM0] upgrade a module ? " + moduleName+ ", " + tech + ", " + allTechName.Contains(tech) + ", " + (HighLogic.CurrentGame.Mode != Game.Modes.SANDBOX)); if (moduleName == null || moduleName.Length == 0 || tech == null || (!allTechName.Contains(tech) && HighLogic.CurrentGame.Mode != Game.Modes.SANDBOX)) { return; } Part p = partToUpdate(); //Debug.log("[MUM] upgrade the partPrefab ? " + (p == part) + " ? " + (p == part.partInfo.partPrefab)+ " " + configModule); foreach (ConfigNode config in configModule) { //Debug.log("[MUM] upgrade a module " + p.name + " , " + p.partInfo.moduleInfos.Count + "/ " + p.Modules.Count + " , " + type); //get the module if (type.Equals("replace")) { try { //get the module //ConfigNode node = new ConfigNode(); PartModule mod = p.Modules[config.GetValue("name")]; //mod.Save(node); ////Debug.log("[MUM] before : " + node); mod.Load(config); //node = new ConfigNode(); mod.Save(node); ////Debug.log("[MUM] after : " + node); //Debug.log("[MUM] after (info) : " + mod.GetInfo()); for (int i = 0; i < part.partInfo.moduleInfos.Count; i++) { AvailablePart.ModuleInfo info = part.partInfo.moduleInfos[i]; if (info.moduleName.Equals(mod.moduleName.Replace("Module", ""))) { info.info = mod.GetInfo(); } } } catch (Exception e) { //Debug.log("[MUM] can't MODIFY " + e); } } else if (type.Equals("create")) { try { PartModule mod = createModule(p, config); //Debug.log("[MUM] added : " + mod); } catch (Exception e) { //Debug.log("[MUM] can't ADD " + e); } } else if (type.Equals("delete")) { try { //Debug.log("[MUM] delete : " + p.Modules[config.GetValue("name")]); removeModuleAndInfo(p, p.Modules[config.GetValue("name")]); } catch (Exception e) { //Debug.log("[MUM] can't REMOVE " + e); } } //Debug.log("[MUM] relance "); } }
//called only in the prefab public override void Restore(ConfigNode initialNode) { Part p = partToUpdate(); ////Debug.log("[MUM] Restore '" + configModule + "' for initialNode node :" + initialNode); foreach (ConfigNode config in configModule) { string moduleUpgradeName = config.GetValue("name"); ////Debug.log("[MUM] Restore a module " + config.GetValue("name") + " " + p.partInfo.moduleInfos.Count + "/ " // + p.Modules.Count + " , " + type + " persisted=" + persisted); if (type.Equals("replace")) { try { //get the module PartModule mod = p.Modules[moduleUpgradeName]; //module exist? (it can be created from an upgrade not already done) if (mod != null) { //get the node in the initialNode foreach (ConfigNode intialModuleNode in initialNode.GetNodes("MODULE")) { ////Debug.log("[MUM] search module " + intialModuleNode.GetValue("name")); if (intialModuleNode.GetValue("name") == moduleUpgradeName) { //Debug.log("[MUM] Restore: replace values in " + moduleUpgradeName); mod.Load(intialModuleNode); } } //Restore info for (int i = 0; i < part.partInfo.moduleInfos.Count; i++) { AvailablePart.ModuleInfo info = part.partInfo.moduleInfos[i]; if (info.moduleName.Equals(mod.moduleName.Replace("Module", ""))) { info.info = mod.GetInfo(); } } } } catch (Exception e) { //Debug.log("[MUM] can't MODIFY " + p.Modules.Count + " : " + e); } } else if (type.Equals("delete")) { try { //do not add if already here if (!p.Modules.Contains(moduleUpgradeName)) { //Debug.log("[MUM] Restore : delete " + moduleUpgradeName); PartModule module = createModule(p, config); //TODO: test if null. if (module == null) { //Debug.logError("[MUM] Error : can't recreate the partmodule " + moduleUpgradeName); } //DONT DO THAT \/, it mess the name/index map of Parmodulelist //swap all module to be at the right place // Totally useless. But i do it. In case of a mod use the index. //PartModule previousModule = module; //PartModule nextModule = null; //for (int i = 0; i < p.Modules.Count; i++) //{ // nextModule = p.Modules[i]; // p.Modules[i] = previousModule; // previousModule = nextModule; //} // when upgrading with delete, the partmodule order is mess up anyway. // it doesn't mess up my test save, but it may be dangerous... } else { //Debug.log("[MUM] not create from Restore delete because module already here"); } } catch (Exception e) { //Debug.log("[MUM] can't ADD (from Restore of delete) " + e); } } else if (type.Equals("create")) { try { //do not del if not here if (p.Modules.Contains(moduleUpgradeName)) { //Debug.log("[MUM] delete : " + type); removeModuleAndInfo(p, p.Modules[moduleUpgradeName]); } else { //Debug.log("[MUM] do not del (Restore create) because it's not inside"); } } catch (Exception e) { //Debug.log("[MUM] can't REMOVE (from Restore of create) " + p.Modules.Count); } } } }
public virtual void SetConfiguration(string newConfiguration = null, bool resetTechLevels = false) { if (newConfiguration == null) newConfiguration = configuration; ConfigSaveLoad(); ConfigNode newConfig = configs.Find (c => c.GetValue ("name").Equals (newConfiguration)); if (!UnlockedConfig(newConfig, part)) { if(newConfig == null) Debug.Log("*RFMEC* ERROR Can't find configuration " + newConfiguration + ", falling back to first tech-available config."); foreach(ConfigNode cfg in configs) if (UnlockedConfig(cfg, part)) { newConfig = cfg; newConfiguration = cfg.GetValue("name"); break; } } if (newConfig != null) { if (configuration != newConfiguration && resetTechLevels) techLevel = origTechLevel; // for asmi if (useConfigAsTitle) part.partInfo.title = configuration; configuration = newConfiguration; config = new ConfigNode("MODULE"); newConfig.CopyTo(config); config.name = "MODULE"; #if DEBUG print ("replacing " + type + " with:"); print (newConfig.ToString ()); #endif pModule = null; // get correct module pModule = GetSpecifiedModule(part, engineID, moduleIndex, type, useWeakType); if ((object)pModule == null) { Debug.Log("*RFMEC* Could not find appropriate module of type " + type + ", with ID=" + engineID + " and index " + moduleIndex); return; } Type mType = pModule.GetType(); config.SetValue("name", mType.Name); // clear all FloatCurves we need to clear (i.e. if our config has one, or techlevels are enabled) bool delAtmo = config.HasNode("atmosphereCurve") || techLevel >= 0; bool delDens = config.HasNode("atmCurve") || techLevel >= 0; bool delVel = config.HasNode("velCurve") || techLevel >= 0; foreach (FieldInfo field in mType.GetFields()) { if (field.FieldType == typeof(FloatCurve) && ((field.Name.Equals("atmosphereCurve") && delAtmo) || (field.Name.Equals("atmCurve") && delDens) || (field.Name.Equals("velCurve") && delVel))) { field.SetValue(pModule, new FloatCurve()); } } // clear propellant gauges foreach (FieldInfo field in mType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)) { if (field.FieldType == typeof(Dictionary<Propellant, VInfoBox>)) { Dictionary<Propellant, VInfoBox> boxes = (Dictionary<Propellant, VInfoBox>)(field.GetValue(pModule)); if (boxes == null) continue; foreach (VInfoBox v in boxes.Values) { if (v == null) //just in case... continue; try { part.stackIcon.RemoveInfo(v); } catch (Exception e) { Debug.Log("*RFMEC* Trying to remove info box: " + e.Message); } } boxes.Clear(); } } if (type.Equals("ModuleRCS") || type.Equals("ModuleRCSFX")) { ModuleRCS rcs = (ModuleRCS)pModule; if (rcs != null) { DoConfig(config); if (config.HasNode("PROPELLANT")) { rcs.propellants.Clear(); } pModule.Load(config); } } else { // is an ENGINE ModuleEngines mE = (ModuleEngines)pModule; if (mE != null) { if (config.HasNode("PROPELLANT")) { mE.propellants.Clear(); } } DoConfig(config); // Handle Engine Ignitor if (config.HasNode("ModuleEngineIgnitor")) { if (part.Modules.Contains("ModuleEngineIgnitor")) { ConfigNode eiNode = config.GetNode("ModuleEngineIgnitor"); if (eiNode.HasValue("ignitionsAvailable")) { int ignitions; if (int.TryParse(eiNode.GetValue("ignitionsAvailable"), out ignitions)) { ignitions = ConfigIgnitions(ignitions); eiNode.SetValue("ignitionsAvailable", ignitions.ToString()); if (eiNode.HasValue("ignitionsRemained")) eiNode.SetValue("ignitionsRemained", ignitions.ToString()); else eiNode.AddValue("ignitionsRemained", ignitions.ToString()); } } if (!HighLogic.LoadedSceneIsEditor && !(HighLogic.LoadedSceneIsFlight && vessel != null && vessel.situation == Vessel.Situations.PRELAUNCH)) // fix for prelaunch { int remaining = (int)(part.Modules["ModuleEngineIgnitor"].GetType().GetField("ignitionsRemained").GetValue(part.Modules["ModuleEngineIgnitor"])); if (eiNode.HasValue("ignitionsRemained")) eiNode.SetValue("ignitionsRemained", remaining.ToString()); else eiNode.AddValue("ignitionsRemained", remaining.ToString()); } ConfigNode tNode = new ConfigNode("MODULE"); eiNode.CopyTo(tNode); tNode.SetValue("name", "ModuleEngineIgnitor"); part.Modules["ModuleEngineIgnitor"].Load(tNode); } else // backwards compatible with EI nodes when using RF ullage etc. { ConfigNode eiNode = config.GetNode("ModuleEngineIgnitor"); if (eiNode.HasValue("ignitionsAvailable") && !config.HasValue("ignitions")) { config.AddValue("ignitions", eiNode.GetValue("ignitionsAvailable")); } if (eiNode.HasValue("useUllageSimulation") && !config.HasValue("ullage")) config.AddValue("ullage", eiNode.GetValue("useUllageSimulation")); if (eiNode.HasValue("isPressureFed") && !config.HasValue("pressureFed")) config.AddValue("pressureFed", eiNode.GetValue("isPressureFed")); if (!config.HasNode("IGNITOR_RESOURCE")) foreach (ConfigNode resNode in eiNode.GetNodes("IGNITOR_RESOURCE")) config.AddNode(resNode); } } if (config.HasValue("ignitions")) { int ignitions; if ((!HighLogic.LoadedSceneIsFlight || (vessel != null && vessel.situation == Vessel.Situations.PRELAUNCH))) { if (int.TryParse(config.GetValue("ignitions"), out ignitions)) { ignitions = ConfigIgnitions(ignitions); config.SetValue("ignitions", ignitions.ToString()); } } else config.RemoveValue("ignitions"); } if (pModule is ModuleEnginesRF) (pModule as ModuleEnginesRF).SetScale(1d); pModule.Load(config); } // fix for editor NaN if (part.Resources.Contains("ElectricCharge") && part.Resources["ElectricCharge"].maxAmount < 0.1) { // hacking around a KSP bug here part.Resources["ElectricCharge"].amount = 0; part.Resources["ElectricCharge"].maxAmount = 0.1; } // set gimbal if (config.HasValue("gimbalRange")) { float newGimbal = float.Parse(config.GetValue("gimbalRange")); for (int m = 0; m < part.Modules.Count; ++m) { if (part.Modules[m] is ModuleGimbal) { ModuleGimbal g = part.Modules[m] as ModuleGimbal; if (gimbalTransform.Equals("") || g.gimbalTransformName.Equals(gimbalTransform)) { g.gimbalRange = newGimbal; break; } } } } if (config.HasValue("cost")) configCost = scale * float.Parse(config.GetValue("cost")); else configCost = 0f; UpdateOtherModules(config); // GUI disabled for now - UpdateTweakableMenu(); // Finally, fire the modified event // more trouble than it is worth... /*if((object)(EditorLogic.fetch) != null && (object)(EditorLogic.fetch.ship) != null && HighLogic.LoadedSceneIsEditor) GameEvents.onEditorShipModified.Fire(EditorLogic.fetch.ship);*/ // fire config modified event /*if(HighLogic.LoadedSceneIsEditor || HighLogic.LoadedSceneIsFlight) EngineConfigChanged();*/ // do it manually List<Part> parts; if (HighLogic.LoadedSceneIsEditor && EditorLogic.fetch.ship != null) parts = EditorLogic.fetch.ship.parts; else if (HighLogic.LoadedSceneIsFlight && vessel != null) parts = vessel.parts; else parts = new List<Part>(); for (int i = parts.Count - 1; i >= 0; --i) parts[i].SendMessage("UpdateUsedBy"); SetupFX(); UpdateTFInterops(); // update TestFlight if it's installed } else { Debug.Log("*RFMEC* ERROR could not find configuration of name " + configuration + " and could find no fallback config."); Debug.Log("For part " + part.name + ", Current nodes:" + Utilities.PrintConfigs(configs)); } }
private void CheckAndFixDockingHatches(List <Part> listParts) { foreach (Part part in listParts) { // If the part does not have any modules set up then move to the next part if (null == part.Modules) { continue; } List <ModuleDockingNode> listDockNodes = new List <ModuleDockingNode>(); List <ModuleDockingHatch> listDockHatches = new List <ModuleDockingHatch>(); // Build a temporary list of docking nodes to consider. This is necassery can we can not add hatch modules to the modules list while we are enumerating the very same list! foreach (ModuleDockingNode dockNode in part.Modules.OfType <ModuleDockingNode>()) { listDockNodes.Add(dockNode); } foreach (ModuleDockingHatch dockHatch in part.Modules.OfType <ModuleDockingHatch>()) { listDockHatches.Add(dockHatch); } // First go through all the hatches. If any do not refer to a dockingPort then remove it. foreach (ModuleDockingHatch dockHatch in listDockHatches) { // I know we are making abit of a meal of this. It is unclear to me what the unset vakues will be, and this way we are catching every possibility. It seems that open (3) is the open that gets called, but I will leave this as is for now. if ("" == dockHatch.docNodeAttachmentNodeName && "" == dockHatch.docNodeTransformName) { Debug.Log("Found a hatch that does not reference a docking node. Removing it from the part.(1)"); part.RemoveModule(dockHatch); } else if (string.Empty == dockHatch.docNodeAttachmentNodeName && string.Empty == dockHatch.docNodeTransformName) { Debug.Log("Found a hatch that does not reference a docking node. Removing it from the part.(2)"); part.RemoveModule(dockHatch); } else if (null == dockHatch.docNodeAttachmentNodeName && null == dockHatch.docNodeTransformName) { Debug.Log("Found a hatch that does not reference a docking node. Removing it from the part.(3)"); part.RemoveModule(dockHatch); } else if ((null == dockHatch.docNodeAttachmentNodeName || string.Empty == dockHatch.docNodeAttachmentNodeName || "" == dockHatch.docNodeAttachmentNodeName) && ("" == dockHatch.docNodeTransformName || string.Empty == dockHatch.docNodeTransformName || null == dockHatch.docNodeTransformName)) { Debug.Log("Found a hatch that does not reference a docking node. Removing it from the part.(4)"); part.RemoveModule(dockHatch); } } // Now because we might have removed for dodgy hatches, rebuild the hatch list. listDockHatches.Clear(); foreach (ModuleDockingHatch dockHatch in part.Modules.OfType <ModuleDockingHatch>()) { listDockHatches.Add(dockHatch); } // Now go through all the dockingPorts and add hatches for any docking ports that do not have one. foreach (ModuleDockingNode dockNode in listDockNodes) { // Does this docking node have a corresponding hatch? ModuleDockingHatch hatch = null; foreach (ModuleDockingHatch h in listDockHatches) { if (h.IsRelatedDockingNode(dockNode)) { hatch = h; break; } } if (null == hatch) { // There is no corresponding hatch - add one. ConfigNode node = new ConfigNode("MODULE"); node.AddValue("name", "ModuleDockingHatch"); if (dockNode.referenceAttachNode != string.Empty) { // Debug.Log("Adding ModuleDockingHatch to part " + part.partInfo.title + " and the docking node that uses attachNode " + dockNode.referenceAttachNode); node.AddValue("docNodeAttachmentNodeName", dockNode.referenceAttachNode); } else { if (dockNode.nodeTransformName != string.Empty) { // Debug.Log("Adding ModuleDockingHatch to part " + part.partInfo.title + " and the docking node that uses transform " + dockNode.nodeTransformName); node.AddValue("docNodeTransformName", dockNode.nodeTransformName); } } { // This block is required as calling AddModule and passing in the node throws an exception if Awake has not been called. The method Awaken uses reflection to call then private method Awake. See http://forum.kerbalspaceprogram.com/threads/27851 for more information. PartModule pm = part.AddModule("ModuleDockingHatch"); if (Awaken(pm)) { // Debug.Log("Loading the ModuleDockingHatch config"); pm.Load(node); } else { Debug.LogWarning("Failed to call Awaken so the config has not been loaded."); } } } } } }
// Method to add Docking Hatches to all parts that have Docking Nodes private void AddHatchModuleToParts() { // If we are in the editor or if flight, take a look at the active vesssel and add a ModuleDockingHatch to any part that has a ModuleDockingNode without a corresponding ModuleDockingHatch List <Part> listParts; if (HighLogic.LoadedSceneIsEditor && null != EditorLogic.startPod) { listParts = EditorLogic.SortedShipList; } else if (HighLogic.LoadedSceneIsFlight && null != FlightGlobals.ActiveVessel && null != FlightGlobals.ActiveVessel.Parts) { listParts = FlightGlobals.ActiveVessel.Parts; } else { listParts = new List <Part>(); } foreach (Part part in listParts) { try { // If the part does not have any modules set up then move to the next part if (null == part.Modules) { continue; } List <ModuleDockingNode> listDockNodes = new List <ModuleDockingNode>(); List <ModuleDockingHatch> listDockHatches = new List <ModuleDockingHatch>(); // Build a temporary list of docking nodes to consider. This is necassery can we can not add hatch modules to the modules list while we are enumerating the very same list! foreach (ModuleDockingNode dockNode in part.Modules.OfType <ModuleDockingNode>()) { listDockNodes.Add(dockNode); } foreach (ModuleDockingHatch dockHatch in part.Modules.OfType <ModuleDockingHatch>()) { listDockHatches.Add(dockHatch); } foreach (ModuleDockingNode dockNode in listDockNodes) { // Does this docking node have a corresponding hatch? ModuleDockingHatch hatch = null; foreach (ModuleDockingHatch h in listDockHatches) { if (h.IsRelatedDockingNode(dockNode)) { hatch = h; break; } } if (null == hatch) { // There is no corresponding hatch - add one. ConfigNode node = new ConfigNode("MODULE"); node.AddValue("name", "ModuleDockingHatch"); if (dockNode.referenceAttachNode != string.Empty) { //Debug.Log("Adding ModuleDockingHatch to part " + part.partInfo.title + " and the docking node that uses attachNode " + dockNode.referenceAttachNode); node.AddValue("docNodeAttachmentNodeName", dockNode.referenceAttachNode); } else { if (dockNode.nodeTransformName != string.Empty) { //Debug.Log("Adding ModuleDockingHatch to part " + part.partInfo.title + " and the docking node that uses transform " + dockNode.nodeTransformName); node.AddValue("docNodeTransformName", dockNode.nodeTransformName); } } { // This block is required as calling AddModule and passing in the node throws an exception if Awake has not been called. The method Awaken uses reflection to call then private method Awake. See http://forum.kerbalspaceprogram.com/threads/27851 for more information. PartModule pm = part.AddModule("ModuleDockingHatch"); if (Awaken(pm)) { //Debug.Log("Loading the ModuleDockingHatch config"); pm.Load(node); } else { Debug.LogWarning("Failed to call Awaken so the config has not been loaded."); } } } } } catch (Exception ex) { Debug.LogException(ex); } } }
public void Activate() => module.Load(dataNode);