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);
                    }
                }
            }
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        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);
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        /// <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);
        }
Exemplo n.º 7
0
        /// <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);
        }
Exemplo n.º 8
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);
        }
Exemplo n.º 10
0
        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);
        }
Exemplo n.º 11
0
        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);
        }
Exemplo n.º 12
0
        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);
        }
Exemplo n.º 14
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);
        }
Exemplo n.º 15
0
        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);
        }
Exemplo n.º 16
0
        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);
        }