private void ApplyUpgrades(UpgradePrefab prefab) { Dictionary <PartModule, bool> moduleUpgraded = new Dictionary <PartModule, bool>(); foreach (PartModule pm in prefab.part.Modules) { if (pm.upgradesApplied.Count > 0) { moduleUpgraded.Add(pm, true); } else { moduleUpgraded.Add(pm, false); } } // Enable upgrades in the handler to reflect the state of user selection for this part foreach (PartUpgrade pu in prefab.upgrades) { if (pu.upgradeState == PartUpgrade.UpgradeState.Disabled) { PartUpgradeManager.Handler.SetEnabled(pu.upgradeName, false); } else { PartUpgradeManager.Handler.SetEnabled(pu.upgradeName, true); } } // Apply upgrades on modules // Due to ApplyUpgrades() not doing anything when all upgrades are disabled // I need to do OnLoad from the config node to revert the module fields to their // default value in this case int i = 0; ConfigNode[] moduleNodes = prefab.part.partInfo.partConfig.GetNodes("MODULE"); foreach (PartModule pm in prefab.part.Modules) { pm.ApplyUpgrades(PartModule.StartState.Editor); bool wasUpgraded = false; moduleUpgraded.TryGetValue(pm, out wasUpgraded); if (wasUpgraded && pm.upgradesApplied.Count == 0) // THIS DON'T WORK FOR A ModuleDataTransmitter. WHY ? { pm.OnAwake(); if (moduleNodes != null) { if (moduleNodes.Count() > i) { if (moduleNodes[i].GetValue("name") == pm.moduleName) { pm.Load(moduleNodes[i]); // OnLoad() isn't enough (issue #4). ex : ok for ModuleEngines, not ok for ModuleDataTransmitter. } } } // In case of a PartStatsUpgradeModule, things get ugly because I've got no public function // that reset the module mass/cost modifiers, so I manually set them to 0. For part fields // modifiers I'm forced to parse the upgrade node to reset the corresponding part fields to // their config value. // TODO : test this with a more complex multi-node stats module if (pm is PartStatsUpgradeModule) { PartStatsUpgradeModule psum = (PartStatsUpgradeModule)pm; psum.costOffset = 0; psum.massOffset = 0; if (psum.upgradeNode != null) { foreach (ConfigNode.Value v in psum.upgradeNode.values) { if (v.name != "mass" && v.name != "cost" && v.name != "massAdd " && v.name != "costAdd") { try { FieldInfo partField = prefab.part.GetType().GetField(v.name); partField.SetValue(prefab.part, Convert.ChangeType(prefab.part.partInfo.partConfig.GetValue(v.name), partField.FieldType)); } catch (Exception) { Debug.LogError("[UpgradesUIextensions] Could not revert part field \"" + v.name + "\" to initial value"); } } } } } pm.ApplyUpgrades(PartModule.StartState.Editor); } i++; } }
private void UpdateModuleWidgetInfo(UpgradePrefab upgradePrefab) { // Update every module widget : int i = 0; List <PartModule> modules = upgradePrefab.part.Modules.GetModules <PartModule>().OrderBy(p => p.GUIName).ToList(); foreach (PartListTooltipWidget widget in tooltip.panelExtended.GetComponentsInChildren <PartListTooltipWidget>(true)) { // Resource widgets are named "PartListTooltipExtendedResourceInfo(Clone)" // Module widgets are named "PartListTooltipExtendedPartInfo(Clone)" if (widget.name == "PartListTooltipExtendedPartInfo(Clone)" && modules.Count >= i) { while (true) { string widgetTitle; string widgetText; // Get the upgrades-updated module text info from our special prefab try { widgetTitle = modules[i].GUIName; widgetText = modules[i].GetInfo(); } catch (Exception) { widgetTitle = widget.textName.text; widgetText = widget.textInfo.text; Debug.LogWarning("[UpgradesUIextensions] Could not retrieve module text for module " + modules[i].GUIName); } // Stock doesn't create a widget for modules that return an empty GetInfo(), but seems to be // checking against an already parsed string where control characters are removed if (RemoveControlCharacters(widgetText).Equals("")) { i++; } // The module has a widget text, we update it with some extra info on the applied upgrades else { // Special formatting for PartStatsUpgradeModule if (modules[i] is PartStatsUpgradeModule) { widgetTitle = "Part stats upgrade"; widgetText = ""; if (!(modules[i].upgradesApplied.Count() > 0)) { widgetText += "No stats modifications in current upgrades"; } else { if (modules[i].showUpgradesInModuleInfo) { widgetText += "<b>Current upgrades:\n</b>"; foreach (string upgrade in modules[i].upgradesApplied) { widgetText += "<b>" + PartUpgradeManager.Handler.GetUpgrade(upgrade).title + "</b>\n"; } widgetText += "\n<color=#99ff00ff><b>Modified stats :</b></color>\n"; } PartStatsUpgradeModule psum = (PartStatsUpgradeModule)modules[i]; if (psum.GetModuleCost(upgradePrefab.part.partInfo.cost, ModifierStagingSituation.CURRENT) > float.Epsilon || psum.GetModuleCost(upgradePrefab.part.partInfo.cost, ModifierStagingSituation.CURRENT) < -float.Epsilon) { widgetText += "<b>Cost modifier : </b>" + psum.GetModuleCost(upgradePrefab.part.partInfo.cost, ModifierStagingSituation.CURRENT).ToString("+ 0;- #") + " <sprite=2 tint=1>\n"; } if (psum.GetModuleMass(upgradePrefab.part.mass, ModifierStagingSituation.CURRENT) > float.Epsilon || psum.GetModuleMass(upgradePrefab.part.mass, ModifierStagingSituation.CURRENT) < -float.Epsilon) { widgetText += "<b>Mass modifier : </b>" + psum.GetModuleMass(upgradePrefab.part.mass, ModifierStagingSituation.CURRENT).ToString("+ 0.###;- #.###") + " t\n"; } if (psum.upgradeNode != null) { foreach (ConfigNode.Value value in psum.upgradeNode.values) { if (value.name != "cost" && value.name != "costAdd" && value.name != "mass" && value.name != "massAdd") { widgetText += "<b>New " + value.name + ": </b>" + value.value + " \n"; } } } } } // All other modules : append upgrade text if showUpgradesInModuleInfo is set to true in the module cfg else { if (modules[i].showUpgradesInModuleInfo) { if (modules[i].upgradesApplied.Count() > 0) { widgetText += "\n<color=#99ff00ff><b>Upgrades :</b></color>\n"; foreach (string upgrade in modules[i].upgradesApplied) { widgetText += "<b>- " + PartUpgradeManager.Handler.GetUpgrade(upgrade).title + ":</b>\n"; ConfigNode cn = modules[i].upgrades.Find(p => p.GetValue("name__") == upgrade); widgetText += cn.GetValue("description__") + "\n"; } } // This is the "Upgrades available at <techtree nodes>..." text, seems totally bugged in 1.2.2 : // it usually show the already applied upgrades but sometimes also the "outdated" upgrade // widgetText += "\n" + part.Modules.GetModule(i).PrintUpgrades(); } } widget.Setup(widgetTitle, widgetText); i++; break; } } } } }