public override bool Load(ConfigNode configNode) { // Load base class bool valid = base.Load(configNode); valid &= ConfigNodeUtil.ParseValue <string>(configNode, "basename", x => basename = x, this); int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "CONDITION")) { DataNode childDataNode = new DataNode("CONDITION_" + index++, dataNode, this); try { ConfigNodeUtil.SetCurrentDataNode(childDataNode); CloseBase.ConditionDetail cd = new CloseBase.ConditionDetail(); valid &= ConfigNodeUtil.ParseValue <CloseBase.ConditionDetail.Condition>(child, "condition", x => cd.condition = x, this); valid &= ConfigNodeUtil.ParseValue <string>(child, "parameter", x => cd.parameter = x, this, "", x => ValidateMandatoryParameter(x, cd.condition)); conditions.Add(cd); } finally { ConfigNodeUtil.SetCurrentDataNode(dataNode); } } valid &= ConfigNodeUtil.ValidateMandatoryChild(configNode, "CONDITION", this); return(valid); }
protected override void OnLoad(ConfigNode configNode) { foreach (string node in map.Keys) { foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, node)) { foreach (ConfigNode.Value pair in child.values) { ExpVal expVal = new ExpVal(pair.name, pair.value); if (factory != null) { ConfigNodeUtil.ParseValue <string>(child, pair.name, x => expVal.val = x, factory); } // Parse the expression to validate parser.ParseExpression(pair.name, expVal.val, dataNode); // Store it for later map[node].Add(expVal); } } } foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "PARAMETER_COMPLETED")) { string parameter = ConfigNodeUtil.ParseValue <string>(child, "parameter"); foreach (ConfigNode.Value pair in child.values) { if (pair.name != "parameter") { ExpVal expVal = new ExpVal(pair.name, pair.value); if (factory != null) { ConfigNodeUtil.ParseValue <string>(child, pair.name, x => expVal.val = x, factory); } // Parse the expression to validate parser.ParseExpression(pair.name, expVal.val, dataNode); // Store it for later if (!onParameterComplete.ContainsKey(parameter)) { onParameterComplete[parameter] = new List <ExpVal>(); } onParameterComplete[parameter].Add(expVal); } } } }
public static OrbitGenerator Create(ConfigNode configNode, CelestialBody defaultBody, OrbitGeneratorFactory factory) { OrbitGenerator obGenerator = new OrbitGenerator(); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode)) { DataNode dataNode = new DataNode("ORBIT_" + index++, factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); OrbitData obData = new OrbitData(child.name); // Get settings that differ by type if (child.name == "FIXED_ORBIT") { valid &= ConfigNodeUtil.ValidateMandatoryChild(child, "ORBIT", factory); obData.orbit = new OrbitSnapshot(ConfigNodeUtil.GetChildNode(child, "ORBIT")).Load(); } else if (child.name == "RANDOM_ORBIT") { valid &= ConfigNodeUtil.ParseValue <OrbitType>(child, "type", x => obData.orbitType = x, factory); valid &= ConfigNodeUtil.ParseValue <int>(child, "count", x => obData.count = x, factory, 1, x => Validation.GE(x, 1)); } else { throw new ArgumentException("Unrecognized orbit node: '" + child.name + "'"); } // Get target body valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", x => obData.orbit.referenceBody = x, factory, defaultBody, Validation.NotNull); // Add to the list obGenerator.orbits.Add(obData); } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } } allOrbitGenerators.Add(obGenerator); return(valid ? obGenerator : null); }
protected override void OnLoad(ConfigNode configNode) { foreach (string node in map.Keys.Union(new string[] { "PARAMETER_COMPLETED" })) { foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, node)) { string parameter = ConfigNodeUtil.ParseValue <string>(child, "parameter", ""); Type type = ConfigNodeUtil.ParseValue <Type>(child, "type", typeof(double)); foreach (ConfigNode.Value pair in child.values) { if (pair.name != "parameter" && pair.name != "type" && !string.IsNullOrEmpty(pair.value)) { ExpVal expVal = new ExpVal(type, pair.name, pair.value); if (factory != null) { ConfigNodeUtil.ParseValue <string>(child, pair.name, x => expVal.val = x, factory, s => { // Parse the expression to validate BaseParser parser = BaseParser.NewParser(expVal.type); parser.ParseExpressionGeneric(pair.name, s, dataNode); return(true); }); } else { // Parse the expression to validate BaseParser parser = BaseParser.NewParser(expVal.type); parser.ParseExpressionGeneric(pair.name, expVal.val, dataNode); } // Store it for later if (child.name == "PARAMETER_COMPLETED") { if (!onParameterComplete.ContainsKey(parameter)) { onParameterComplete[parameter] = new List <ExpVal>(); } onParameterComplete[parameter].Add(expVal); } else { map[node].Add(expVal); } } } } } }
public override bool Load(ConfigNode configNode) { // Load base class bool valid = base.Load(configNode); valid &= ConfigNodeUtil.ParseValue <TriggeredBehaviour.State>(configNode, "onState", x => onState = x, this, TriggeredBehaviour.State.CONTRACT_SUCCESS); if (onState == TriggeredBehaviour.State.PARAMETER_COMPLETED || onState == TriggeredBehaviour.State.PARAMETER_FAILED) { valid &= ConfigNodeUtil.ParseValue <List <string> >(configNode, "parameter", x => parameter = x, this); } kerbalInfo = new List <ChangeKerbalType.KerbalInfo>(); int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "KERBAL_INFO")) { string kerbInfoNode = "KERBAL_INFO" + index++; DataNode childDataNode = new DataNode(kerbInfoNode, dataNode, this); try { ConfigNodeUtil.SetCurrentDataNode(childDataNode); ChangeKerbalType.KerbalInfo kerb = new ChangeKerbalType.KerbalInfo(); kerbalInfo.Add(kerb); valid &= ConfigNodeUtil.ParseValue <Kerbal>(child, "kerbal", x => kerb.kerbal = x, this); valid &= ConfigNodeUtil.ParseValue <ProtoCrewMember.KerbalType?>(child, "kerbalType", x => kerb.kerbalType = x, this, (ProtoCrewMember.KerbalType?)null); valid &= ConfigNodeUtil.ParseValue <string>(child, "trait", x => kerb.trait = x, this, ""); } finally { ConfigNodeUtil.SetCurrentDataNode(dataNode); } } valid &= ConfigNodeUtil.ValidateMandatoryChild(configNode, "KERBAL_INFO", this); return(valid); }
/// <summary> /// Loads the ITERATOR nodes. /// </summary> /// <param name="node"></param> /// <returns>Whether the load was successful</returns> public static bool LoadIteratorNodes(ConfigNode node, IContractConfiguratorFactory obj) { bool valid = true; IEnumerable <ConfigNode> iteratorNodes = ConfigNodeUtil.GetChildNodes(node, "ITERATOR"); if (!iteratorNodes.Any()) { return(true); } else if (iteratorNodes.Count() > 1) { LoggingUtil.LogError(obj, "Multiple ITERATOR nodes found - only one iterator node allowed."); return(false); } ConfigNode iteratorNode = iteratorNodes.First(); DataNode iteratorDataNode = new DataNode("ITERATOR", obj.dataNode, obj); try { ConfigNodeUtil.SetCurrentDataNode(iteratorDataNode); valid &= ConfigNodeUtil.ParseValue <Type>(iteratorNode, "type", x => obj.iteratorType = x, obj); if (obj.iteratorType != null) { foreach (ConfigNode.Value pair in iteratorNode.values) { string name = pair.name; if (name != "type") { if (!string.IsNullOrEmpty(obj.iteratorKey)) { LoggingUtil.LogError(obj, "Multiple key values found in ITERATOR node - only one key allowed."); return(false); } // Create the list type Type listType = typeof(List <>); listType = listType.MakeGenericType(new Type[] { obj.iteratorType }); // Create the setter function object value = null; Type listActionType = typeof(Action <>).MakeGenericType(listType); Delegate listDelegate = Delegate.CreateDelegate(listActionType, value, typeof(DataNode).GetMethod("NullAction")); // Get the ParseValue method MethodInfo parseListMethod = parseMethodGeneric.MakeGenericMethod(new Type[] { listType }); // Invoke the ParseValue method valid &= (bool)parseListMethod.Invoke(null, new object[] { iteratorNode, name, listDelegate, obj }); // Store the iterator key for later obj.iteratorKey = name; } } } // Load didn't get us a key if (string.IsNullOrEmpty(obj.iteratorKey)) { LoggingUtil.LogError(obj, "No key field was defined for the ITERATOR!."); return(false); } } finally { ConfigNodeUtil.SetCurrentDataNode(obj.dataNode); } // Add a dummy value to the parent data node node.AddValue(obj.iteratorKey, "@ITERATOR/" + obj.iteratorKey + ".ElementAt(IteratorCurrentIndex())"); node.AddValue("iteratorCount", "@ITERATOR/" + obj.iteratorKey + ".Count()"); return(valid); }
/// <summary> /// Parses the child DATA nodes out of the given config node, and returns the parsed values back in dataValues. /// </summary> /// <param name="configNode">The ConfigNode to load child DATA nodes from.</param> /// <param name="obj">The ContractConfigurator object to load from.</param> /// <param name="dataValues"></param> /// <param name="uniquenessChecks"></param> /// <returns></returns> public bool ParseDataNodes(ConfigNode configNode, IContractConfiguratorFactory obj, Dictionary <string, ContractType.DataValueInfo> dataValues, Dictionary <string, UniquenessCheck> uniquenessChecks) { bool valid = true; foreach (ConfigNode data in ConfigNodeUtil.GetChildNodes(configNode, "DATA")) { Type type = null; bool requiredValue = true; bool hidden = true; bool isLiteral = false; string title = ""; ConfigNodeUtil.SetCurrentDataNode(null); valid &= ConfigNodeUtil.ParseValue <Type>(data, "type", x => type = x, obj); valid &= ConfigNodeUtil.ParseValue <bool>(data, "requiredValue", x => requiredValue = x, obj, true); valid &= ConfigNodeUtil.ParseValue <string>(data, "title", x => title = x, obj, ""); valid &= ConfigNodeUtil.ParseValue <bool>(data, "hidden", x => hidden = x, obj, false); valid &= ConfigNodeUtil.ParseValue <bool>(data, "isLiteral", x => isLiteral = x, obj, false); bool doneTitleWarning = false; UniquenessCheck uniquenessCheck = UniquenessCheck.NONE; // Backwards compatibility for Contract Configurator 1.8.3 if (data.HasValue("uniqueValue") || data.HasValue("activeUniqueValue")) { LoggingUtil.LogWarning(this, "The use of uniqueValue and activeUniqueValue is obsolete since Contract Configurator 1.9.0, use uniquenessCheck instead."); bool uniqueValue = false; bool activeUniqueValue = false; valid &= ConfigNodeUtil.ParseValue <bool>(data, "uniqueValue", x => uniqueValue = x, obj, false); valid &= ConfigNodeUtil.ParseValue <bool>(data, "activeUniqueValue", x => activeUniqueValue = x, obj, false); uniquenessCheck = activeUniqueValue ? UniquenessCheck.CONTRACT_ACTIVE : uniqueValue ? UniquenessCheck.CONTRACT_ALL : UniquenessCheck.NONE; } else { valid &= ConfigNodeUtil.ParseValue <UniquenessCheck>(data, "uniquenessCheck", x => uniquenessCheck = x, obj, UniquenessCheck.NONE); } ConfigNodeUtil.SetCurrentDataNode(this); if (type != null) { foreach (ConfigNode.Value pair in data.values) { string name = pair.name; if (name != "type" && name != "title" && name != "hidden" && name != "requiredValue" && name != "uniqueValue" && name != "activeUniqueValue" && name != "uniquenessCheck" && name != "isLiteral") { if (uniquenessCheck != UniquenessCheck.NONE) { uniquenessChecks[name] = uniquenessCheck; } object value = null; // Create the setter function Type actionType = typeof(Action <>).MakeGenericType(type); Delegate del = Delegate.CreateDelegate(actionType, value, typeof(DataNode).GetMethod("NullAction")); // Set the ParseValue method generic MethodInfo method = (isLiteral ? methodParseValueLiteral : methodParseValue).MakeGenericMethod(new Type[] { type }); // Invoke the ParseValue method if (isLiteral) { this[name] = method.Invoke(null, new object[] { data, name, false }); } else { valid &= (bool)method.Invoke(null, new object[] { data, name, del, obj }); } dataValues[name] = new ContractType.DataValueInfo(title, requiredValue, hidden, type); // Recommend a title if (!data.HasValue("title") && requiredValue && !IsDeterministic(name) && !hidden && !doneTitleWarning && !dataValues[name].IsIgnoredType()) { doneTitleWarning = true; LoggingUtil.Log(obj.minVersion >= ContractConfigurator.ENHANCED_UI_VERSION ? LoggingUtil.LogLevel.ERROR : LoggingUtil.LogLevel.WARNING, this, obj.ErrorPrefix() + ": " + name + ": The field 'title' is required in for data node values where 'requiredValue' is true. Alternatively, the attribute 'hidden' can be set to true (but be careful - this can cause player confusion if all lines for the contract type show as 'Met' and the contract isn't generating)."); // Error on newer versions of contract packs if (obj.minVersion >= ContractConfigurator.ENHANCED_UI_VERSION) { valid = false; } } } } } } return(valid); }
public static WaypointGenerator Create(ConfigNode configNode, WaypointGeneratorFactory factory) { WaypointGenerator wpGenerator = new WaypointGenerator(); // Waypoint Manager integration EventData <string> onWaypointIconAdded = GameEvents.FindEvent <EventData <string> >("OnWaypointIconAdded"); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode)) { DataNode dataNode = new DataNode("WAYPOINT_" + index, factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); dataNode["type"] = child.name; double? altitude = null; WaypointData wpData = new WaypointData(child.name); // Use an expression to default - then it'll work for dynamic contracts if (!child.HasValue("targetBody")) { child.AddValue("targetBody", "@/targetBody"); } valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", x => wpData.waypoint.celestialName = x != null ? x.name : "", factory); valid &= ConfigNodeUtil.ParseValue <List <string> >(child, "name", x => wpData.names = x, factory, new List <string>()); valid &= ConfigNodeUtil.ParseValue <double?>(child, "altitude", x => altitude = x, factory, (double?)null); valid &= ConfigNodeUtil.ParseValue <List <string> >(child, "parameter", x => wpData.parameter = x, factory, new List <string>()); valid &= ConfigNodeUtil.ParseValue <bool>(child, "hidden", x => wpData.waypoint.visible = !x, factory, false); Action <string> assignWaypoint = (x) => { wpData.waypoint.id = x; if (onWaypointIconAdded != null) { onWaypointIconAdded.Fire(x); } }; if (!wpData.waypoint.visible) { valid &= ConfigNodeUtil.ParseValue <string>(child, "icon", assignWaypoint, factory, ""); } else { valid &= ConfigNodeUtil.ParseValue <string>(child, "icon", assignWaypoint, factory); } valid &= ConfigNodeUtil.ParseValue <bool>(child, "underwater", x => wpData.underwater = x, factory, false); valid &= ConfigNodeUtil.ParseValue <bool>(child, "clustered", x => wpData.waypoint.isClustered = x, factory, false); // Track the index wpData.waypoint.index = index++; // Get altitude if (altitude == null) { wpData.waypoint.altitude = 0.0; wpData.randomAltitude = true; } else { wpData.waypoint.altitude = altitude.Value; } // Get settings that differ by type if (child.name == "WAYPOINT") { valid &= ConfigNodeUtil.ParseValue <double>(child, "latitude", x => wpData.waypoint.latitude = x, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "longitude", x => wpData.waypoint.longitude = x, factory); } else if (child.name == "RANDOM_WAYPOINT") { // Get settings for randomization valid &= ConfigNodeUtil.ParseValue <bool>(child, "waterAllowed", x => wpData.waterAllowed = x, factory, true); valid &= ConfigNodeUtil.ParseValue <bool>(child, "forceEquatorial", x => wpData.forceEquatorial = x, factory, false); valid &= ConfigNodeUtil.ParseValue <int>(child, "count", x => wpData.count = x, factory, 1, x => Validation.GE(x, 1)); } else if (child.name == "RANDOM_WAYPOINT_NEAR") { // Get settings for randomization valid &= ConfigNodeUtil.ParseValue <bool>(child, "waterAllowed", x => wpData.waterAllowed = x, factory, true); // Get near waypoint details valid &= ConfigNodeUtil.ParseValue <int>(child, "nearIndex", x => wpData.nearIndex = x, factory, x => Validation.GE(x, 0) && Validation.LT(x, wpGenerator.waypoints.Count)); valid &= ConfigNodeUtil.ParseValue <bool>(child, "chained", x => wpData.chained = x, factory, false); valid &= ConfigNodeUtil.ParseValue <int>(child, "count", x => wpData.count = x, factory, 1, x => Validation.GE(x, 1)); // Get distances valid &= ConfigNodeUtil.ParseValue <double>(child, "minDistance", x => wpData.minDistance = x, factory, 0.0, x => Validation.GE(x, 0.0)); valid &= ConfigNodeUtil.ParseValue <double>(child, "maxDistance", x => wpData.maxDistance = x, factory, x => Validation.GT(x, 0.0)); } else if (child.name == "PQS_CITY") { wpData.randomAltitude = false; string dummy = null; valid &= ConfigNodeUtil.ParseValue <string>(child, "pqsCity", x => dummy = x, factory, x => { bool v = true; if (!string.IsNullOrEmpty(wpData.waypoint.celestialName)) { try { CelestialBody body = FlightGlobals.Bodies.Where(b => b.name == wpData.waypoint.celestialName).First(); wpData.pqsCity = body.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == x).First(); } catch (Exception e) { LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load PQSCity with name '{0}'", x); LoggingUtil.LogException(e); v = false; } } else { // Force this to get re-run when the targetBody is loaded throw new DataNode.ValueNotInitialized("/targetBody"); } return(v); }); valid &= ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset", x => wpData.pqsOffset = x, factory, new Vector3d()); } else if (child.name == "LAUNCH_SITE") { wpData.randomAltitude = false; string dummy = null; valid &= ConfigNodeUtil.ParseValue <string>(child, "launchSite", x => dummy = x, factory, x => { bool v = true; if (!string.IsNullOrEmpty(wpData.waypoint.celestialName)) { try { wpData.launchSite = ConfigNodeUtil.ParseLaunchSiteValue(x); } catch (Exception e) { LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load Launch Site with name '{0}'", x); LoggingUtil.LogException(e); v = false; } } else { // Force this to get re-run when the targetBody is loaded throw new DataNode.ValueNotInitialized("/targetBody"); } return(v); }); valid &= ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset", x => wpData.pqsOffset = x, factory, new Vector3d()); } else { LoggingUtil.LogError(factory, "Unrecognized waypoint node: '{0}'", child.name); valid = false; } // Check for unexpected values valid &= ConfigNodeUtil.ValidateUnexpectedValues(child, factory); // Copy waypoint data WaypointData old = wpData; wpData = new WaypointData(old, null); wpGenerator.waypoints.Add(wpData); } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } } return(valid ? wpGenerator : null); }
public static WaypointGenerator Create(ConfigNode configNode, WaypointGeneratorFactory factory) { WaypointGenerator wpGenerator = new WaypointGenerator(); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode)) { DataNode dataNode = new DataNode("WAYPOINT_" + index, factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); dataNode["type"] = child.name; double? altitude = null; WaypointData wpData = new WaypointData(child.name); // Use an expression to default - then it'll work for dynamic contracts if (!child.HasValue("targetBody")) { child.AddValue("targetBody", "@/targetBody"); } valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", x => wpData.waypoint.celestialName = x != null ? x.name : "", factory); valid &= ConfigNodeUtil.ParseValue <List <string> >(child, "name", x => wpData.names = x, factory, new List <string>()); valid &= ConfigNodeUtil.ParseValue <double?>(child, "altitude", x => altitude = x, factory, (double?)null); valid &= ConfigNodeUtil.ParseValue <List <string> >(child, "parameter", x => wpData.parameter = x, factory, new List <string>()); valid &= ConfigNodeUtil.ParseValue <bool>(child, "hidden", x => wpData.waypoint.visible = !x, factory, false); if (!wpData.waypoint.visible) { valid &= ConfigNodeUtil.ParseValue <string>(child, "icon", x => wpData.waypoint.id = x, factory, ""); } else { valid &= ConfigNodeUtil.ParseValue <string>(child, "icon", x => wpData.waypoint.id = x, factory); } // The FinePrint logic is such that it will only look in Squad/Contracts/Icons for icons. // Cheat this by hacking the path in the game database. if (wpData.waypoint.id.Contains("/")) { GameDatabase.TextureInfo texInfo = GameDatabase.Instance.databaseTexture.Where(t => t.name == wpData.waypoint.id).FirstOrDefault(); if (texInfo != null) { texInfo.name = "Squad/Contracts/Icons/" + wpData.waypoint.id; } } valid &= ConfigNodeUtil.ParseValue <bool>(child, "underwater", x => wpData.underwater = x, factory, false); valid &= ConfigNodeUtil.ParseValue <bool>(child, "clustered", x => wpData.waypoint.isClustered = x, factory, false); // Track the index wpData.waypoint.index = index++; // Get altitude if (altitude == null) { wpData.waypoint.altitude = 0.0; wpData.randomAltitude = true; } else { wpData.waypoint.altitude = altitude.Value; } // Get settings that differ by type if (child.name == "WAYPOINT") { valid &= ConfigNodeUtil.ParseValue <double>(child, "latitude", x => wpData.waypoint.latitude = x, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "longitude", x => wpData.waypoint.longitude = x, factory); } else if (child.name == "RANDOM_WAYPOINT") { // Get settings for randomization valid &= ConfigNodeUtil.ParseValue <bool>(child, "waterAllowed", x => wpData.waterAllowed = x, factory, true); valid &= ConfigNodeUtil.ParseValue <bool>(child, "forceEquatorial", x => wpData.forceEquatorial = x, factory, false); valid &= ConfigNodeUtil.ParseValue <int>(child, "count", x => wpData.count = x, factory, 1, x => Validation.GE(x, 1)); } else if (child.name == "RANDOM_WAYPOINT_NEAR") { // Get settings for randomization valid &= ConfigNodeUtil.ParseValue <bool>(child, "waterAllowed", x => wpData.waterAllowed = x, factory, true); // Get near waypoint details valid &= ConfigNodeUtil.ParseValue <int>(child, "nearIndex", x => wpData.nearIndex = x, factory, x => Validation.GE(x, 0) && Validation.LT(x, wpGenerator.waypoints.Count)); valid &= ConfigNodeUtil.ParseValue <bool>(child, "chained", x => wpData.chained = x, factory, false); valid &= ConfigNodeUtil.ParseValue <int>(child, "count", x => wpData.count = x, factory, 1, x => Validation.GE(x, 1)); // Get distances valid &= ConfigNodeUtil.ParseValue <double>(child, "minDistance", x => wpData.minDistance = x, factory, 0.0, x => Validation.GE(x, 0.0)); valid &= ConfigNodeUtil.ParseValue <double>(child, "maxDistance", x => wpData.maxDistance = x, factory, x => Validation.GT(x, 0.0)); } else if (child.name == "PQS_CITY") { wpData.randomAltitude = false; string dummy = null; valid &= ConfigNodeUtil.ParseValue <string>(child, "pqsCity", x => dummy = x, factory, x => { bool v = true; if (!string.IsNullOrEmpty(wpData.waypoint.celestialName)) { try { CelestialBody body = FlightGlobals.Bodies.Where(b => b.name == wpData.waypoint.celestialName).First(); wpData.pqsCity = body.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == x).First(); } catch (Exception e) { LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load PQSCity with name '" + x + "'"); LoggingUtil.LogException(e); v = false; } } else { // Force this to get re-run when the targetBody is loaded throw new DataNode.ValueNotInitialized("/targetBody"); } return(v); }); valid &= ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset", x => wpData.pqsOffset = x, factory, new Vector3d()); } else { LoggingUtil.LogError(factory, "Unrecognized waypoint node: '" + child.name + "'"); valid = false; } // Check for unexpected values valid &= ConfigNodeUtil.ValidateUnexpectedValues(child, factory); // Copy waypoint data WaypointData old = wpData; for (int i = 0; i < old.count; i++) { wpData = new WaypointData(old, null); wpGenerator.waypoints.Add(wpData); if (old.parameter.Any()) { wpData.parameter = new List <string>(); wpData.parameter.Add(old.parameter.Count() == 1 ? old.parameter.First() : old.parameter.ElementAtOrDefault(i)); } // Set the name if (old.names.Any()) { wpData.waypoint.name = (old.names.Count() == 1 ? old.names.First() : old.names.ElementAtOrDefault(i)); } if (string.IsNullOrEmpty(wpData.waypoint.name) || wpData.waypoint.name.ToLower() == "site") { wpData.waypoint.name = StringUtilities.GenerateSiteName(random.Next(), wpData.waypoint.celestialBody, !wpData.waterAllowed); } // Handle waypoint chaining if (wpData.chained && i != 0) { wpData.nearIndex = wpGenerator.waypoints.Count - 2; } } } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } } return(valid ? wpGenerator : null); }
public static OrbitGenerator Create(ConfigNode configNode, OrbitGeneratorFactory factory) { OrbitGenerator obGenerator = new OrbitGenerator(); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode)) { DataNode dataNode = new DataNode("ORBIT_" + index++, factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); OrbitData obData = new OrbitData(child.name); // Get settings that differ by type if (child.name == "FIXED_ORBIT") { valid &= ConfigNodeUtil.ParseValue <Orbit>(child, "ORBIT", x => obData.orbit = x, factory); } else if (child.name == "RANDOM_ORBIT") { valid &= ConfigNodeUtil.ParseValue <OrbitType>(child, "type", x => obData.orbitType = x, factory); valid &= ConfigNodeUtil.ParseValue <int>(child, "count", x => obData.count = x, factory, 1, x => Validation.GE(x, 1)); valid &= ConfigNodeUtil.ParseValue <double>(child, "altitudeFactor", x => obData.altitudeFactor = x, factory, 0.8, x => Validation.Between(x, 0.0, 1.0)); valid &= ConfigNodeUtil.ParseValue <double>(child, "inclinationFactor", x => obData.inclinationFactor = x, factory, 0.8, x => Validation.Between(x, 0.0, 1.0)); valid &= ConfigNodeUtil.ParseValue <double>(child, "eccentricity", x => obData.eccentricity = x, factory, 0.0, x => Validation.GE(x, 0.0)); valid &= ConfigNodeUtil.ParseValue <double>(child, "deviationWindow", x => obData.deviationWindow = x, factory, 10.0, x => Validation.GE(x, 0.0)); } else { throw new ArgumentException("Unrecognized orbit node: '" + child.name + "'"); } // Use an expression to default - then it'll work for dynamic contracts if (!child.HasValue("targetBody")) { child.AddValue("targetBody", "@/targetBody"); } valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", x => obData.targetBody = x, factory); // Check for unexpected values valid &= ConfigNodeUtil.ValidateUnexpectedValues(child, factory); // Add to the list obGenerator.orbits.Add(obData); if (dataNode.IsInitialized("targetBody") && dataNode.IsInitialized("type")) { valid &= obGenerator.ValidateOrbitType(obData, factory); } } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } } return(valid ? obGenerator : null); }
public static SpawnKerbal Create(ConfigNode configNode, SpawnKerbalFactory factory) { SpawnKerbal spawnKerbal = new SpawnKerbal(); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "KERBAL")) { DataNode dataNode = new DataNode("KERBAL_" + index++, factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); KerbalData kd = new KerbalData(); // Use an expression to default - then it'll work for dynamic contracts if (!child.HasValue("targetBody")) { child.AddValue("targetBody", "@/targetBody"); } valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", x => kd.body = x, factory); // Get landed stuff if (child.HasValue("lat") && child.HasValue("lon") || child.HasValue("pqsCity")) { kd.landed = true; if (child.HasValue("pqsCity")) { string pqsCityStr = null; valid &= ConfigNodeUtil.ParseValue <string>(child, "pqsCity", x => pqsCityStr = x, factory); if (pqsCityStr != null) { try { kd.pqsCity = kd.body.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == pqsCityStr).First(); } catch (Exception e) { LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load PQSCity with name '" + pqsCityStr + "'"); LoggingUtil.LogException(e); valid = false; } } valid &= ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset", x => kd.pqsOffset = x, factory, new Vector3d()); // Don't expect these to load anything, but do it to mark as initialized valid &= ConfigNodeUtil.ParseValue <double>(child, "lat", x => kd.latitude = x, factory, 0.0); valid &= ConfigNodeUtil.ParseValue <double>(child, "lon", x => kd.longitude = x, factory, 0.0); } else { valid &= ConfigNodeUtil.ParseValue <double>(child, "lat", x => kd.latitude = x, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "lon", x => kd.longitude = x, factory); } valid &= ConfigNodeUtil.ParseValue <float>(child, "heading", x => kd.heading = x, factory, 0.0f); } // Get orbit else if (child.HasNode("ORBIT")) { // Don't expect these to load anything, but do it to mark as initialized valid &= ConfigNodeUtil.ParseValue <double>(child, "lat", x => kd.latitude = x, factory, 0.0); valid &= ConfigNodeUtil.ParseValue <double>(child, "lon", x => kd.longitude = x, factory, 0.0); valid &= ConfigNodeUtil.ParseValue <Orbit>(child, "ORBIT", x => kd.orbit = x, factory); } else { // Will error valid &= ConfigNodeUtil.ValidateMandatoryChild(child, "ORBIT", factory); } valid &= ConfigNodeUtil.ParseValue <double?>(child, "alt", x => kd.altitude = x, factory, (double?)null); if (child.HasValue("kerbal")) { valid &= ConfigNodeUtil.ParseValue <Kerbal>(child, "kerbal", x => kd.kerbal = x, factory); } else { // Default gender if (!child.HasValue("gender")) { child.AddValue("gender", "Random()"); } valid &= ConfigNodeUtil.ParseValue <ProtoCrewMember.Gender>(child, "gender", x => kd.kerbal.gender = x, factory); // Default name if (!child.HasValue("name")) { child.AddValue("name", "RandomKerbalName(@gender)"); } valid &= ConfigNodeUtil.ParseValue <string>(child, "name", x => { kd.kerbal.name = x; if (kd.kerbal.pcm != null) { kd.kerbal.pcm.ChangeName(x); } }, factory); } // Get additional stuff valid &= ConfigNodeUtil.ParseValue <bool>(child, "owned", x => kd.owned = x, factory, false); valid &= ConfigNodeUtil.ParseValue <bool>(child, "addToRoster", x => kd.addToRoster = x, factory, true); valid &= ConfigNodeUtil.ParseValue <ProtoCrewMember.KerbalType>(child, "kerbalType", x => kd.kerbal.kerbalType = x, factory, ProtoCrewMember.KerbalType.Unowned); // Check for unexpected values valid &= ConfigNodeUtil.ValidateUnexpectedValues(child, factory); // Add to the list spawnKerbal.kerbals.Add(kd); } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } } return(valid ? spawnKerbal : null); }
public static SpawnVessel Create(ConfigNode configNode, SpawnVesselFactory factory) { SpawnVessel spawnVessel = new SpawnVessel(); ConfigNodeUtil.ParseValue <bool>(configNode, "deferVesselCreation", x => spawnVessel.deferVesselCreation = x, factory, false); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "VESSEL")) { DataNode dataNode = new DataNode("VESSEL_" + index++, factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); VesselData vessel = new VesselData(); // Get name if (child.HasValue("name")) { valid &= ConfigNodeUtil.ParseValue <string>(child, "name", x => vessel.name = x, factory); } // Get craft details if (child.HasValue("craftURL")) { valid &= ConfigNodeUtil.ParseValue <string>(child, "craftURL", x => vessel.craftURL = x, factory); } if (child.HasValue("craftPart")) { valid &= ConfigNodeUtil.ParseValue <AvailablePart>(child, "craftPart", x => vessel.craftPart = x, factory); } valid &= ConfigNodeUtil.AtLeastOne(child, new string[] { "craftURL", "craftPart" }, factory); valid &= ConfigNodeUtil.ParseValue <string>(child, "flagURL", x => vessel.flagURL = x, factory, (string)null); valid &= ConfigNodeUtil.ParseValue <VesselType>(child, "vesselType", x => vessel.vesselType = x, factory, VesselType.Ship); // Use an expression to default - then it'll work for dynamic contracts if (!child.HasValue("targetBody")) { child.AddValue("targetBody", "@/targetBody"); } valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", x => vessel.body = x, factory); // Get landed stuff if (child.HasValue("pqsCity")) { string pqsCityStr = null; valid &= ConfigNodeUtil.ParseValue <string>(child, "pqsCity", x => pqsCityStr = x, factory); if (pqsCityStr != null) { try { vessel.pqsCity = vessel.body.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == pqsCityStr).First(); } catch (Exception e) { LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load PQSCity with name '" + pqsCityStr + "'"); LoggingUtil.LogException(e); valid = false; } } valid &= ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset", x => vessel.pqsOffset = x, factory, new Vector3d()); // Don't expect these to load anything, but do it to mark as initialized valid &= ConfigNodeUtil.ParseValue <double>(child, "lat", x => vessel.latitude = x, factory, 0.0); valid &= ConfigNodeUtil.ParseValue <double>(child, "lon", x => vessel.longitude = x, factory, 0.0); // Do load alt and height valid &= ConfigNodeUtil.ParseValue <double?>(child, "alt", x => vessel.altitude = x, factory, (double?)null); valid &= ConfigNodeUtil.ParseValue <float>(child, "height", x => vessel.height = x, factory, !string.IsNullOrEmpty(vessel.craftURL) ? 0.0f : 2.5f); vessel.orbiting = false; } else if (child.HasValue("lat") && child.HasValue("lon")) { valid &= ConfigNodeUtil.ParseValue <double>(child, "lat", x => vessel.latitude = x, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "lon", x => vessel.longitude = x, factory); valid &= ConfigNodeUtil.ParseValue <double?>(child, "alt", x => vessel.altitude = x, factory, (double?)null); valid &= ConfigNodeUtil.ParseValue <float>(child, "height", x => vessel.height = x, factory, !string.IsNullOrEmpty(vessel.craftURL) ? 0.0f : 2.5f); vessel.orbiting = false; } // Get orbit else { valid &= ConfigNodeUtil.ParseValue <Orbit>(child, "ORBIT", x => vessel.orbit = x, factory); vessel.orbiting = true; } valid &= ConfigNodeUtil.ParseValue <float>(child, "heading", x => vessel.heading = x, factory, 0.0f); valid &= ConfigNodeUtil.ParseValue <float>(child, "pitch", x => vessel.pitch = x, factory, 0.0f); valid &= ConfigNodeUtil.ParseValue <float>(child, "roll", x => vessel.roll = x, factory, 0.0f); // Get additional flags valid &= ConfigNodeUtil.ParseValue <bool>(child, "owned", x => vessel.owned = x, factory, false); // Handle the CREW nodes foreach (ConfigNode crewNode in ConfigNodeUtil.GetChildNodes(child, "CREW")) { int count = 1; valid &= ConfigNodeUtil.ParseValue <int>(crewNode, "count", x => count = x, factory, 1); for (int i = 0; i < count; i++) { CrewData cd = new CrewData(); // Read crew details valid &= ConfigNodeUtil.ParseValue <string>(crewNode, "name", x => cd.name = x, factory, (string)null); valid &= ConfigNodeUtil.ParseValue <bool>(crewNode, "addToRoster", x => cd.addToRoster = x, factory, true); // Check for unexpected values valid &= ConfigNodeUtil.ValidateUnexpectedValues(crewNode, factory); // Add the record vessel.crew.Add(cd); } } // Check for unexpected values valid &= ConfigNodeUtil.ValidateUnexpectedValues(child, factory); // Add to the list spawnVessel.vessels.Add(vessel); } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } } if (!configNode.HasNode("VESSEL")) { valid = false; LoggingUtil.LogError(factory, "SpawnVessel requires at least one VESSEL node."); } return(valid ? spawnVessel : null); }
public static SpawnVessel Create(ConfigNode configNode, CelestialBody defaultBody, SpawnVesselFactory factory) { SpawnVessel spawnVessel = new SpawnVessel(); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "VESSEL")) { DataNode dataNode = new DataNode("VESSEL_" + index++, factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); VesselData vessel = new VesselData(); // Get name if (child.HasValue("name")) { vessel.name = child.GetValue("name"); } // Get paths vessel.craftURL = ConfigNodeUtil.ParseValue <string>(child, "craftURL"); vessel.flagURL = ConfigNodeUtil.ParseValue <string>(child, "flagURL", (string)null); vessel.vesselType = ConfigNodeUtil.ParseValue <VesselType>(child, "vesselType", VesselType.Ship); // Get celestial body valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", x => vessel.body = x, factory, defaultBody, Validation.NotNull); // Get landed stuff if (child.HasValue("lat") && child.HasValue("lon")) { valid &= ConfigNodeUtil.ParseValue <double>(child, "lat", x => vessel.latitude = x, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "lon", x => vessel.longitude = x, factory); valid &= ConfigNodeUtil.ParseValue <double?>(child, "alt", x => vessel.altitude = x, factory, (double?)null); vessel.landed = true; } // Get orbit else { valid &= ConfigNodeUtil.ValidateMandatoryChild(child, "ORBIT", factory); vessel.orbit = new OrbitSnapshot(ConfigNodeUtil.GetChildNode(child, "ORBIT")).Load(); vessel.orbit.referenceBody = vessel.body; } // Get additional flags valid &= ConfigNodeUtil.ParseValue <bool>(child, "owned", x => vessel.owned = x, factory, false); // Handle the CREW nodes foreach (ConfigNode crewNode in ConfigNodeUtil.GetChildNodes(child, "CREW")) { int count = 1; valid &= ConfigNodeUtil.ParseValue <int>(crewNode, "count", x => count = x, factory, 1); for (int i = 0; i < count; i++) { CrewData cd = new CrewData(); // Read crew details valid &= ConfigNodeUtil.ParseValue <string>(crewNode, "name", x => cd.name = x, factory, (string)null); valid &= ConfigNodeUtil.ParseValue <bool>(crewNode, "addToRoster", x => cd.addToRoster = x, factory, true); // Add the record vessel.crew.Add(cd); } } // Add to the list spawnVessel.vessels.Add(vessel); } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } } return(valid ? spawnVessel : null); }
public static WaypointGenerator Create(ConfigNode configNode, CelestialBody defaultBody, WaypointGeneratorFactory factory) { WaypointGenerator wpGenerator = new WaypointGenerator(); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode)) { double? altitude = null; WaypointData wpData = new WaypointData(child.name); valid &= ConfigNodeUtil.ParseValue <string>(child, "targetBody", x => wpData.waypoint.celestialName = x, factory, defaultBody != null ? defaultBody.name : null, Validation.NotNull); valid &= ConfigNodeUtil.ParseValue <string>(child, "name", x => wpData.waypoint.name = x, factory, (string)null); valid &= ConfigNodeUtil.ParseValue <double?>(child, "altitude", x => altitude = x, factory, (double?)null); valid &= ConfigNodeUtil.ParseValue <string>(child, "parameter", x => wpData.parameter = x, factory, ""); valid &= ConfigNodeUtil.ParseValue <bool>(child, "hidden", x => wpData.hidden = x, factory, false); if (wpData.hidden) { valid &= ConfigNodeUtil.ParseValue <string>(child, "icon", x => wpData.waypoint.id = x, factory, ""); } else { valid &= ConfigNodeUtil.ParseValue <string>(child, "icon", x => wpData.waypoint.id = x, factory); } // The FinePrint logic is such that it will only look in Squad/Contracts/Icons for icons. // Cheat this by hacking the path in the game database. if (wpData.waypoint.id.Contains("/")) { GameDatabase.TextureInfo texInfo = GameDatabase.Instance.databaseTexture.Where(t => t.name == wpData.waypoint.id).FirstOrDefault(); if (texInfo != null) { texInfo.name = "Squad/Contracts/Icons/" + wpData.waypoint.id; } } // Track the index wpData.waypoint.index = index++; // Get altitude if (altitude == null) { wpData.waypoint.altitude = 0.0; wpData.randomAltitude = true; } else { wpData.waypoint.altitude = altitude.Value; } DataNode dataNode = new DataNode("WAYPOINT_" + (index - 1), factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); // Get settings that differ by type if (child.name == "WAYPOINT") { valid &= ConfigNodeUtil.ParseValue <double>(child, "latitude", x => wpData.waypoint.latitude = x, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "longitude", x => wpData.waypoint.longitude = x, factory); } else if (child.name == "RANDOM_WAYPOINT") { // Get settings for randomization valid &= ConfigNodeUtil.ParseValue <bool>(child, "waterAllowed", x => wpData.waterAllowed = x, factory, true); valid &= ConfigNodeUtil.ParseValue <bool>(child, "forceEquatorial", x => wpData.forceEquatorial = x, factory, false); valid &= ConfigNodeUtil.ParseValue <int>(child, "count", x => wpData.count = x, factory, 1, x => Validation.GE(x, 1)); } else if (child.name == "RANDOM_WAYPOINT_NEAR") { // Get settings for randomization valid &= ConfigNodeUtil.ParseValue <bool>(child, "waterAllowed", x => wpData.waterAllowed = x, factory, true); // Get near waypoint details valid &= ConfigNodeUtil.ParseValue <int>(child, "nearIndex", x => wpData.nearIndex = x, factory, x => Validation.GE(x, 0)); valid &= ConfigNodeUtil.ParseValue <int>(child, "count", x => wpData.count = x, factory, 1, x => Validation.GE(x, 1)); // Get distances valid &= ConfigNodeUtil.ParseValue <double>(child, "minDistance", x => wpData.minDistance = x, factory, 0.0, x => Validation.GE(x, 0.0)); // To be deprecated if (child.HasValue("nearDistance")) { valid &= ConfigNodeUtil.ParseValue <double>(child, "nearDistance", x => wpData.maxDistance = x, factory, x => Validation.GT(x, 0.0)); LoggingUtil.LogWarning(factory, "The 'nearDistance' attribute is obsolete as of Contract Configurator 0.7.4. It will be removed in 1.0.0 in favour of minDistance/maxDistance."); } else { valid &= ConfigNodeUtil.ParseValue <double>(child, "maxDistance", x => wpData.maxDistance = x, factory, x => Validation.GT(x, wpData.minDistance)); } } else if (child.name == "PQS_CITY") { wpData.randomAltitude = false; string pqsCity = null; valid &= ConfigNodeUtil.ParseValue <string>(child, "pqsCity", x => pqsCity = x, factory); if (pqsCity != null) { try { CelestialBody body = FlightGlobals.Bodies.Where(b => b.name == wpData.waypoint.celestialName).First(); wpData.pqsCity = body.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == pqsCity).First(); } catch (Exception e) { LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load PQSCity with name '" + pqsCity + "'"); LoggingUtil.LogException(e); valid = false; } } valid &= ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset", x => wpData.pqsOffset = x, factory, new Vector3d()); } else { LoggingUtil.LogError(factory, "Unrecognized waypoint node: '" + child.name + "'"); valid = false; } } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } // Add to the list wpGenerator.waypoints.Add(wpData); } return(valid ? wpGenerator : null); }
public override bool Load(ConfigNode configNode) { // Load base class bool valid = base.Load(configNode); int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "DIALOG_BOX")) { string dialogBoxNode = "DIALOG_BOX_" + index++; DataNode childDataNode = new DataNode(dialogBoxNode, dataNode, this); try { ConfigNodeUtil.SetCurrentDataNode(childDataNode); DialogBox.DialogDetail detail = new DialogBox.DialogDetail(); details.Add(detail); valid &= ConfigNodeUtil.ParseValue <DialogBox.TriggerCondition>(child, "condition", x => detail.condition = x, this); valid &= ConfigNodeUtil.ParseValue <DialogBox.Position>(child, "position", x => detail.position = x, this, DialogBox.Position.LEFT); valid &= ConfigNodeUtil.ParseValue <float>(child, "width", x => detail.width = x, this, 0.8f, x => Validation.Between(x, 0.0f, 1.0f)); valid &= ConfigNodeUtil.ParseValue <float>(child, "height", x => detail.height = x, this, 0.0f, x => Validation.Between(x, 0.0f, 1.0f)); valid &= ConfigNodeUtil.ParseValue <string>(child, "title", x => detail.title = x, this, ""); valid &= ConfigNodeUtil.ParseValue <Color>(child, "titleColor", x => detail.titleColor = x, this, Color.white); valid &= ConfigNodeUtil.ParseValue <string>(child, "parameter", x => detail.parameter = x, this, (string)null, x => ValidateMandatoryParameter(x, detail.condition)); int sectionIndex = 0; foreach (ConfigNode sectionNode in child.GetNodes()) { DataNode sectionDataNode = new DataNode(dialogBoxNode + "_" + sectionIndex++, childDataNode, this); ConfigNodeUtil.SetCurrentDataNode(sectionDataNode); if (sectionNode.name == "TEXT") { DialogBox.TextSection section = new DialogBox.TextSection(); detail.sections.Add(section); // Parse the text twice, once to ensure parsability, the other to get the unexpanded text valid &= ConfigNodeUtil.ParseValue <string>(sectionNode, "text", x => { }, this); if (valid) { section.text = ConfigNodeUtil.ParseValue <string>(sectionNode, "text"); } valid &= ConfigNodeUtil.ParseValue <Color>(sectionNode, "textColor", x => section.textColor = x, this, new Color(0.8f, 0.8f, 0.8f)); valid &= ConfigNodeUtil.ParseValue <int>(sectionNode, "fontSize", x => section.fontSize = x, this, 20); } else if (sectionNode.name == "IMAGE") { DialogBox.ImageSection section = new DialogBox.ImageSection(); detail.sections.Add(section); valid &= ConfigNodeUtil.ParseValue <string>(sectionNode, "url", x => section.imageURL = x, this, ValidateImageURL); valid &= ConfigNodeUtil.ParseValue <string>(sectionNode, "characterName", x => { section.characterName = x; section.showName = !string.IsNullOrEmpty(x); }, this, ""); valid &= ConfigNodeUtil.ParseValue <Color>(sectionNode, "textColor", x => section.textColor = x, this, new Color(0.729f, 0.855f, 0.333f)); } else if (sectionNode.name == "INSTRUCTOR") { DialogBox.InstructorSection section = new DialogBox.InstructorSection(); detail.sections.Add(section); valid &= ConfigNodeUtil.ParseValue <string>(sectionNode, "name", x => section.name = x, this); valid &= ConfigNodeUtil.ParseValue <bool>(sectionNode, "showName", x => section.showName = x, this, true); valid &= ConfigNodeUtil.ParseValue <string>(sectionNode, "characterName", x => section.characterName = x, this, ""); valid &= ConfigNodeUtil.ParseValue <Color>(sectionNode, "textColor", x => section.textColor = x, this, new Color(0.729f, 0.855f, 0.333f)); valid &= ConfigNodeUtil.ParseValue <DialogBox.InstructorSection.Animation?>(sectionNode, "animation", x => section.animation = x, this, (DialogBox.InstructorSection.Animation?)null); } else if (sectionNode.name == "KERBAL") { DialogBox.KerbalSection section = new DialogBox.KerbalSection(); detail.sections.Add(section); valid &= ConfigNodeUtil.ParseValue <bool>(sectionNode, "showName", x => section.showName = x, this, true); valid &= ConfigNodeUtil.ParseValue <string>(sectionNode, "characterName", x => section.characterName = x, this, ""); valid &= ConfigNodeUtil.ParseValue <ProtoCrewMember.Gender>(sectionNode, "gender", x => section.gender = x, this, ProtoCrewMember.Gender.Male); valid &= ConfigNodeUtil.ParseValue <Color>(sectionNode, "textColor", x => section.textColor = x, this, new Color(0.729f, 0.855f, 0.333f)); valid &= ConfigNodeUtil.ParseValue <int>(sectionNode, "crewIndex", x => section.crewIndex = x, this, 0); valid &= ConfigNodeUtil.ParseValue <List <string> >(sectionNode, "excludeName", x => section.excludeName = x, this, new List <string>()); } else if (sectionNode.name == "BREAK") { DialogBox.BreakSection section = new DialogBox.BreakSection(); detail.sections.Add(section); } } } finally { ConfigNodeUtil.SetCurrentDataNode(dataNode); } } valid &= ConfigNodeUtil.ValidateMandatoryChild(configNode, "DIALOG_BOX", this); return(valid); }
public static SpawnKerbal Create(ConfigNode configNode, CelestialBody defaultBody, SpawnKerbalFactory factory) { SpawnKerbal spawnKerbal = new SpawnKerbal(); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "KERBAL")) { DataNode dataNode = new DataNode("KERBAL_" + index++, factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); KerbalData kerbal = new KerbalData(); // Get name if (child.HasValue("name")) { kerbal.name = child.GetValue("name"); } // Get celestial body valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", x => kerbal.body = x, factory, defaultBody, Validation.NotNull); // Get landed stuff if (child.HasValue("lat") && child.HasValue("lon") || child.HasValue("pqsCity")) { kerbal.landed = true; if (child.HasValue("pqsCity")) { string pqsCityStr = null; valid &= ConfigNodeUtil.ParseValue <string>(child, "pqsCity", x => pqsCityStr = x, factory); if (pqsCityStr != null) { try { kerbal.pqsCity = kerbal.body.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == pqsCityStr).First(); } catch (Exception e) { LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load PQSCity with name '" + pqsCityStr + "'"); LoggingUtil.LogException(e); valid = false; } } valid &= ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset", x => kerbal.pqsOffset = x, factory, new Vector3d()); } else { valid &= ConfigNodeUtil.ParseValue <double>(child, "lat", x => kerbal.latitude = x, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "lon", x => kerbal.longitude = x, factory); } } // Get orbit else if (child.HasNode("ORBIT")) { kerbal.orbit = new OrbitSnapshot(ConfigNodeUtil.GetChildNode(child, "ORBIT")).Load(); kerbal.orbit.referenceBody = kerbal.body; } else { // Will error valid &= ConfigNodeUtil.ValidateMandatoryChild(child, "ORBIT", factory); } valid &= ConfigNodeUtil.ParseValue <double?>(child, "alt", x => kerbal.altitude = x, factory, (double?)null); // Get additional flags valid &= ConfigNodeUtil.ParseValue <bool>(child, "owned", x => kerbal.owned = x, factory, false); valid &= ConfigNodeUtil.ParseValue <bool>(child, "addToRoster", x => kerbal.addToRoster = x, factory, true); // Add to the list spawnKerbal.kerbals.Add(kerbal); } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } } return(valid ? spawnKerbal : null); }