public override LaunchSite ParseIdentifier(Token token) { if (token.sval.Equals("null", StringComparison.CurrentCultureIgnoreCase)) { return(null); } return(ConfigNodeUtil.ParseLaunchSiteValue(token.sval)); }
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); }