/// <summary> /// Given the root config node, load all the switchable resources in it. /// </summary> /// <param name="rootNode"></param> /// <returns></returns> public static SwitchableResource[] Load(ConfigNode rootNode) { if (rootNode.nodes == null) { return(EMPTY); } ConfigNode[] nodes = rootNode.nodes.GetNodes(RESOURCE_TAG); if (nodes.Length < 1) { return(EMPTY); } try { SwitchableResource[] resources = new SwitchableResource[nodes.Length]; for (int i = 0; i < resources.Length; ++i) { resources[i] = new SwitchableResource(nodes[i]); for (int j = 0; j < i; ++j) { if (resources[i].definition.name.Equals(resources[j].definition.name)) { throw new ArgumentException(rootNode.name + ": Contains duplicate definitions for resource '" + resources[i].definition.name + "'"); } } } return(resources); } catch (ArgumentException e) { Logging.Error(rootNode.name + ": Invalid " + RESOURCE_TAG + " found: " + e.Message); return(EMPTY); } }
/// <summary> /// Given a resourcesId and a resource, produce a string representation. /// </summary> /// <param name="format"></param> /// <param name="resource"></param> /// <returns></returns> public static string Format(string resourcesId, SwitchableResource resource) { string text = FormatOf(resourcesId); for (int i = 0; i < formatters.Count; ++i) { if (text.Contains(formatters[i].Key)) { text = text.Replace(formatters[i].Key, formatters[i].Value(resource)); } } return(text); }
/// <summary> /// Here when the game is first loading up. /// </summary> /// <param name="node"></param> private void OnInitialGameLoading(ConfigNode node) { Loader.Initialize(); // Load the resources from config. resources = SwitchableResource.Load(node); longTitle = SwitchableResource.LongTitleOf(resources); // If they haven't specified a resources title in the config, // use the auto-generated long one. if (string.IsNullOrEmpty(displayName)) { displayName = longTitle; } // Add the resources to the global map. This is how the ModuleSimpleFuelSwitch will // control behavior when the player is working with a ship in the editor. SwitchableResourceSet.Add( part.name, resourcesId, displayName, selectorFieldName, ParseLinkedVariants(linkedVariant), isDefault, resources, part.Resources); // Everything else in this class is concerned simply with setting up stuff // to display appropriate info in the part info window from the parts pane // of the vehicle editor. info = FormatInfo(resourcesId, resources); if (resources.Length == 0) { primaryField = longTitle; } else { primaryField = LocalizeUtil.Format( "#SimpleFuelSwitch_primaryInfoFormat", selectorFieldName, displayName, ResourcePrimaryInfoFormatter.Format(resourcesId, resources)); } }
private static string FormatInfo(SwitchableResource[] resources) { // For default parts that aren't using this mod, each resource will // get one pane, where the title is the resource name and the // info consists of three lines: Amount, Mass, Cost. // // In our case, we're adding one pane for a *set* of resources, so // we need to present the info a bit differently. // // The title is fairly straightforward: the specified resources // title for the module (if provided), or a list of resource names // (if not). // // However, we can't really show amount/mass/cost, since there are // multiple panes that may have multiple resources each, so we // need to be more succinct. For each resource, we'll either display // the mass (if it's a resource with density > 0), or the amount // (for zero-density resources). StringBuilder builder = new StringBuilder(); for (int i = 0; i < resources.Length; ++i) { SwitchableResource resource = resources[i]; string amountString = (resource.definition.density > 0) ? FormatMassInTons(resource.maxAmount * resource.definition.density) : FormatAmount(resource.maxAmount); if (i > 0) { builder.Append("\n"); } builder.Append(LocalizeUtil.Format( "#SimpleFuelSwitch_detailedInfoFormat", resource.definition.displayName, amountString)); } return(builder.ToString()); }
/// <summary> /// Here when the game is first loading up. /// </summary> /// <param name="node"></param> private void OnInitialGameLoading(ConfigNode node) { // Load the resources from config and add them to the global map. This is how // the ModuleSimpleFuelSwitch will control behavior when the player is working // with a ship in the editor. resources = SwitchableResource.Load(node); SwitchableResourceSet.Add(part.name, resourcesId, displayName, selectorFieldName, isDefault, resources); // Everything else in this class is concerned simply with setting up stuff // to display appropriate info in the part info window from the parts pane // of the vehicle editor. // Build a long title from the resource names. StringBuilder builder = new StringBuilder(resources[0].definition.displayName); for (int i = 1; i < resources.Length; ++i) { builder.Append(" + "); builder.Append(resources[i].definition.displayName); } longTitle = builder.ToString(); // If they haven't specified a resources title in the config, // use the auto-generated long one. if (displayName == null) { displayName = longTitle; } info = FormatInfo(resources); primaryField = LocalizeUtil.Format( "#SimpleFuelSwitch_primaryInfoFormat", selectorFieldName, displayName, FormatPrimaryFieldQuantity(resources)); }
/// <summary> /// Bring a part's resources into line with the specified resources ID for selection. Returns /// the current selection, or null if there's a problem. /// </summary> /// <param name="part"></param> /// <param name="resourcesId"></param> /// <param name="resetAmounts"></param> public static Selection UpdatePartResourceList(Part part, string resourcesId, bool resetAmounts) { // First, find what selectable resources *should* be there SwitchableResourceSet set = null; if (!resourcesByPartName.TryGetValue(part.name, out set)) { return(null); // no info found for this part } Selection selection = set[resourcesId]; if (selection == null) { return(null); // no such selection available for this part } // Now see if there's anything we should be removing bool isDirty = false; List <string> unwantedResources = null; for (int i = 0; i < part.Resources.Count; ++i) { PartResource resource = part.Resources[i]; if (set.baseResourceNames.Contains(resource.resourceName)) { continue; // included on the base part, so keep it } SwitchableResource switchableResource = selection.TryFind(resource.resourceName); if (switchableResource != null) { if (resetAmounts) { // The resource is one that we want to be on the current part. However, the amount // or maxAmount might be off. resource.maxAmount = switchableResource.maxAmount; resource.amount = switchableResource.amount; } continue; } // It's unwanted. Add it to the list. if (unwantedResources == null) { unwantedResources = new List <string>(); } unwantedResources.Add(resource.resourceName); } if (unwantedResources != null) { isDirty = true; for (int i = 0; i < unwantedResources.Count; ++i) { part.Resources.Remove(unwantedResources[i]); } } // Then see whether there are any missing resources we should be adding for (int i = 0; i < selection.resources.Length; ++i) { SwitchableResource resource = selection.resources[i]; if (!part.Resources.Contains(resource.definition.name)) { isDirty = true; part.Resources.Add(resource.CreateResourceNode()); } } if (isDirty) { // we made changes, so we need to reset some stuff part.SimulationResources.Clear(); part.ResetSimulation(); } return(selection); }
/// <summary> /// Display units of a resource if it's massless, mass in tons if it isn't. /// </summary> /// <param name="resource"></param> /// <returns></returns> private static string QuantityOf(SwitchableResource resource) { return((resource.definition.density > 0) ? MassOf(resource) : UnitsOf(resource)); }
/// <summary> /// Display the mass of a resource, in tons. /// </summary> /// <param name="resource"></param> /// <returns></returns> private static string MassOf(SwitchableResource resource) { return(LocalizeUtil.Format("#SimpleFuelSwitch_massTonsFormat", resource.amount * resource.definition.density)); }
/// <summary> /// Display the number of units of a resource. /// </summary> /// <param name="resource"></param> /// <returns></returns> private static string UnitsOf(SwitchableResource resource) { return(string.Format("{0:0.#}", resource.amount)); }