//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); } }
// See CompilePartInfo public static AvailablePart.ModuleInfo GetModuleInfo(PartModule pm) { AvailablePart.ModuleInfo moduleInfo = new AvailablePart.ModuleInfo(); if (pm is IModuleInfo) { IModuleInfo iModuleInfo = pm as IModuleInfo; moduleInfo.moduleName = iModuleInfo.GetModuleTitle(); moduleInfo.info = iModuleInfo.GetInfo().Trim(); moduleInfo.primaryInfo = iModuleInfo.GetPrimaryField(); } else { moduleInfo.moduleName = (pm.GUIName ?? KSPUtil.PrintModuleName(pm.moduleName)); moduleInfo.info = pm.GetInfo().Trim(); } if (pm.showUpgradesInModuleInfo && pm.HasUpgrades()) { moduleInfo.info += "\n" + pm.PrintUpgrades(); } moduleInfo.moduleDisplayName = pm.GetModuleDisplayName(); if (moduleInfo.moduleDisplayName == string.Empty) { moduleInfo.moduleDisplayName = moduleInfo.moduleName; } return(moduleInfo); }
//to call only on partprefab, as it erase the partinfo public static void removeModuleAndInfo(Part part, PartModule modToRemove) { if (modToRemove == null) { return; } part.RemoveModule(modToRemove); if (modToRemove.GetInfo().Length > 0) { List <AvailablePart.ModuleInfo> allInfos = new List <AvailablePart.ModuleInfo>(); allInfos.AddRange(part.partInfo.moduleInfos); foreach (AvailablePart.ModuleInfo infoToDel in allInfos) { if (infoToDel.moduleName.Equals(modToRemove.moduleName.Replace("Module", ""))) { part.partInfo.moduleInfos.Remove(infoToDel); break; } } } }
private IEnumerator ReloadInfos() { yield return(null); for (int i0 = PartLoader.LoadedPartsList.Count - 1; i0 >= 0; i0--) { AvailablePart aPart = PartLoader.LoadedPartsList[i0]; for (var i1 = aPart.moduleInfos.Count - 1; i1 >= 0; i1--) { Debug.Log("moduleName: " + aPart.moduleInfos[i1].moduleName); var info = aPart.moduleInfos[i1]; string newInfos = ""; if (info.moduleName == "ModulePartInfo") { for (var i2 = aPart.partPrefab.Modules.Count - 1; i2 >= 0; --i2) { if (aPart.partPrefab.Modules[i1].moduleName == "ModulePartInfo") { PartModule pm = aPart.partPrefab.Modules[i2]; newInfos = pm.GetInfo(); break; } } if (newInfos != "") { Debug.Log("info.info (before): " + info.info); Debug.Log("newInfos: " + newInfos); info.info = "\n" + newInfos; //break; Debug.Log("final info.info: " + info.info + ", newInfos: " + newInfos); break; } } } } }
// Returns the info-text of the given part with the given upgrades to be displayed in the GUI-comparison. private String getPartInfo(Part part, KRnDUpgrade upgradesToApply = null) { String info = ""; KRnDUpgrade originalUpgrades = null; try { KRnDModule rndModule = KRnD.getKRnDModule(part); if (rndModule == null || (originalUpgrades = rndModule.getCurrentUpgrades()) == null) { return(info); } // Upgrade the part to get the correct info, we revert it back to its previous values in the finally block below: KRnD.updatePart(part, upgradesToApply); List <ModuleEngines> engineModules = KRnD.getEngineModules(part); ModuleRCS rcsModule = KRnD.getRcsModule(part); ModuleReactionWheel reactionWheelModule = KRnD.getReactionWheelModule(part); ModuleDeployableSolarPanel solarPanelModule = KRnD.getSolarPanelModule(part); ModuleWheelBase landingLegModule = KRnD.getLandingLegModule(part); PartResource electricChargeResource = KRnD.getChargeResource(part); ModuleGenerator generatorModule = KRnD.getGeneratorModule(part); PartModule fissionGenerator = KRnD.getFissionGeneratorModule(part); List <ModuleResourceConverter> converterModules = KRnD.getConverterModules(part); ModuleParachute parachuteModule = KRnD.getParachuteModule(part); ModuleProceduralFairing fairingModule = KRnD.getFairingModule(part); List <PartResource> fuelResources = KRnD.getFuelResources(part); // Basic stats: info = "<color=#FFFFFF><b>Dry Mass:</b> " + part.mass.ToString("0.#### t") + "\n"; info += "<b>Max Temp.:</b> " + part.maxTemp.ToString("0.#") + "/" + part.skinMaxTemp.ToString("0.#") + " °K\n"; if (landingLegModule != null) { info += "<b>Crash Tolerance:</b> " + part.crashTolerance.ToString("0.#### m/s") + "\n"; } if (electricChargeResource != null) { info += "<b>Electric Charge:</b> " + electricChargeResource.maxAmount.ToString() + "\n"; } // Fuels: if (fuelResources != null) { foreach (PartResource fuelResource in fuelResources) { // Reformat resource-names like "ElectricCharge" to "Electric Charge": String fuelName = fuelResource.resourceName.ToString(); fuelName = Regex.Replace(fuelName, @"([a-z])([A-Z])", "$1 $2"); info += "<b>" + fuelName + ":</b> " + fuelResource.maxAmount.ToString() + "\n"; } } // Module stats: info += "\n"; if (engineModules != null) { foreach (ModuleEngines engineModule in engineModules) { info += "<color=#99FF00><b>Engine"; if (engineModules.Count > 1) { info += " (" + engineModule.engineID.ToString() + ")"; } info += ":</b></color>\n" + engineModule.GetInfo(); if (engineModules.Count > 1) { info += "\n"; } } } if (rcsModule) { info += "<color=#99FF00><b>RCS:</b></color>\n" + rcsModule.GetInfo(); } if (reactionWheelModule) { info += "<color=#99FF00><b>Reaction Wheel:</b></color>\n" + reactionWheelModule.GetInfo(); } if (solarPanelModule) { info += "<color=#99FF00><b>Solar Panel:</b></color>\n" + KRnD.getSolarPanelInfo(solarPanelModule); } if (generatorModule) { info += "<color=#99FF00><b>Generator:</b></color>\n" + generatorModule.GetInfo(); } if (fissionGenerator) { info += "<color=#99FF00><b>Fission-Generator:</b></color>\n" + fissionGenerator.GetInfo(); } if (converterModules != null) { foreach (ModuleResourceConverter converterModule in converterModules) { info += "<color=#99FF00><b>Converter " + converterModule.ConverterName + ":</b></color>\n" + converterModule.GetInfo() + "\n"; } } if (parachuteModule) { info += "<color=#99FF00><b>Parachute:</b></color>\n" + parachuteModule.GetInfo(); } if (fairingModule) { info += "<color=#99FF00><b>Fairing:</b></color>\n" + fairingModule.GetInfo(); } info += "</color>"; } catch (Exception e) { Debug.LogError("[KRnDGUI] getPartInfo(): " + e.ToString()); } finally { try { if (originalUpgrades != null) { KRnD.updatePart(part, originalUpgrades); } } catch (Exception e) { Debug.LogError("[KRnDGUI] getPartInfo() restore of part failed: " + e.ToString()); } } return(info); }
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(); } }
//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); } } } }