Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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);
        }