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 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.Name()"); } valid &= ConfigNodeUtil.ParseValue<string>(child, "targetBody", x => wpData.waypoint.celestialName = x, factory, Validation.CheckCelestialBody); 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.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; } } // 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<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, 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 && !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 == 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; } // Check for unexpected values valid &= ConfigNodeUtil.ValidateUnexpectedValues(child, factory); // Generate a random name if (!child.HasValue("name")) { wpData.randomName = true; } // Add to the list 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); } 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 WaypointGenerator Create(ConfigNode configNode, CelestialBody defaultBody, WaypointGeneratorFactory factory) { WaypointGenerator wpGenerator = new WaypointGenerator(); bool valid = true; int index = 0; foreach (ConfigNode child in configNode.GetNodes()) { int count = child.HasValue("count") ? Convert.ToInt32(child.GetValue("count")) : 1; for (int i = 0; i < count; i++) { double? altitude = null; WaypointData wpData = new WaypointData(child.name); valid &= ConfigNodeUtil.ParseValue <string>(child, "targetBody", ref wpData.waypoint.celestialName, factory, defaultBody != null ? defaultBody.name : null, Validation.NotNull); valid &= ConfigNodeUtil.ParseValue <string>(child, "name", ref wpData.waypoint.name, factory, (string)null); valid &= ConfigNodeUtil.ParseValue <string>(child, "icon", ref wpData.waypoint.id, factory); valid &= ConfigNodeUtil.ParseValue <double?>(child, "altitude", ref altitude, factory, (double?)null, x => Validation.GE(x.Value, 0.0)); // 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", ref wpData.waypoint.latitude, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "longitude", ref wpData.waypoint.longitude, factory); } else if (child.name == "RANDOM_WAYPOINT") { // Get settings for randomization valid &= ConfigNodeUtil.ParseValue <bool>(child, "waterAllowed", ref wpData.waterAllowed, factory, true); valid &= ConfigNodeUtil.ParseValue <bool>(child, "forceEquatorial", ref wpData.forceEquatorial, factory, false); } else if (child.name == "RANDOM_WAYPOINT_NEAR") { // Get settings for randomization valid &= ConfigNodeUtil.ParseValue <bool>(child, "waterAllowed", ref wpData.waterAllowed, factory, true); // Get near waypoint details valid &= ConfigNodeUtil.ParseValue <int>(child, "nearIndex", ref wpData.nearIndex, factory, x => Validation.GE(x, 0)); valid &= ConfigNodeUtil.ParseValue <double>(child, "nearDistance", ref wpData.nearDistance, factory, x => Validation.GT(x, 0.0)); } else { throw new ArgumentException("Unrecognized waypoint node: '" + child.name + "'"); } // Add to the list wpGenerator.waypoints.Add(wpData); } } return(valid ? wpGenerator : 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); }