Example #1
0
        protected bool CheckContractGroup(ConfiguredContract contract, ContractGroup group)
        {
            if (group != null)
            {
                // Check the group is enabled
                if (!((ContractGroupParametersTemplate)HighLogic.CurrentGame.Parameters.CustomParams(SettingsBuilder.GroupParametersType)).IsEnabled(group.Root.name))
                {
                    throw new ContractRequirementException("Contract group " + group.name + " is not enabled.");
                }

                IEnumerable <ConfiguredContract> contractList = ConfiguredContract.CurrentContracts.
                                                                Where(c => c.contractType != null && c != contract);

                // Check the group active limit
                int activeContracts = contractList.Count(c => c.contractType != null && group.BelongsToGroup(c.contractType));
                if (group.maxSimultaneous != 0 && activeContracts >= group.maxSimultaneous)
                {
                    throw new ContractRequirementException("Too many active contracts in group (" + group.name + ").");
                }

                // Check the group completed limit
                if (group.maxCompletions != 0)
                {
                    int finishedContracts = ConfiguredContract.CompletedContracts.Count(c => c.contractType != null && group.BelongsToGroup(c.contractType));
                    if (finishedContracts + activeContracts >= maxCompletions)
                    {
                        throw new ContractRequirementException("Too many completed contracts in group (" + group.name + ").");
                    }
                }

                return(CheckContractGroup(contract, group.parent));
            }

            return(true);
        }
Example #2
0
        protected bool CheckContractGroup(ConfiguredContract contract, ContractGroup group)
        {
            if (group != null)
            {
                // Check the group active limit
                int activeContracts = ContractSystem.Instance.GetCurrentContracts <ConfiguredContract>().Count(c => c.contractType != null && group.BelongsToGroup(c.contractType));
                if (contract.ContractState == Contract.State.Offered || contract.ContractState == Contract.State.Active)
                {
                    activeContracts--;
                }

                if (group.maxSimultaneous != 0 && activeContracts >= group.maxSimultaneous)
                {
                    LoggingUtil.LogVerbose(this, "Didn't generate contract type " + name + ", too many active contracts in group.");
                    return(false);
                }

                // Check the group completed limit
                if (group.maxCompletions != 0)
                {
                    int finishedContracts = ContractSystem.Instance.GetCompletedContracts <ConfiguredContract>().Count(c => c.contractType != null && group.BelongsToGroup(c.contractType));
                    if (finishedContracts + activeContracts >= maxCompletions)
                    {
                        LoggingUtil.LogVerbose(this, "Didn't generate contract type " + name + ", too many completed contracts in group.");
                        return(false);
                    }
                }

                return(CheckContractGroup(contract, group.parent));
            }

            return(true);
        }
Example #3
0
        private IEnumerable <ConfiguredContract> ContractEnumerator()
        {
            // Loop through all the contract groups
            IEnumerable <ContractGroup> groups = ContractGroup.AllGroups;

            for (int i = 0; i < groups.Count(); i++)
            {
                nextContractGroup = (nextContractGroup + 1) % groups.Count();
                ContractGroup group = groups.ElementAt(nextContractGroup);

                List <ContractType> contractTypes = ContractType.AllValidContractTypes.ToList();
                contractTypes.Shuffle();
                foreach (ContractType ct in contractTypes)
                {
                    // Is the contract time part of this group, and is it allowed to attempt to generate
                    if (ct.group == group && ct.lastGenerationFailure + FAILURE_WAIT_TIME < Time.realtimeSinceStartup)
                    {
                        if (ct.lastGenerationFailure != -100)
                        {
                            ct.lastGenerationFailure    = -100;
                            ct.failedGenerationAttempts = 0;
                        }

                        // Are we in the right scene, or is is a special contract that can generate in any scene
                        if (HighLogic.LoadedScene == GameScenes.SPACECENTER || ct.autoAccept)
                        {
                            foreach (ConfiguredContract contract in GenerateContract(ct))
                            {
                                yield return(contract);
                            }
                        }
                    }
                }
            }
        }
Example #4
0
        /// <summary>
        /// Static method (used by other mods via reflection) to get the group name.
        /// </summary>
        public static string contractGroupName(Contract c)
        {
            if (c == null || c.GetType() != typeof(ConfiguredContract))
            {
                return("");
            }
            ConfiguredContract cc = (ConfiguredContract)c;

            if (cc.contractType == null)
            {
                return("");
            }

            ContractGroup group = cc.contractType.group;

            if (group == null)
            {
                return("");
            }
            while (group.parent != null)
            {
                group = group.parent;
            }
            return(group.name);
        }
Example #5
0
        public ContractType(string name)
        {
            this.name = name;
            contractTypes.Add(name, this);

            // Member defaults
            group             = null;
            agent             = null;
            minExpiry         = 0;
            maxExpiry         = 0;
            deadline          = 0;
            cancellable       = true;
            declinable        = true;
            autoAccept        = false;
            prestige          = new List <Contract.ContractPrestige>();
            maxCompletions    = 0;
            maxSimultaneous   = 0;
            rewardScience     = 0.0f;
            rewardReputation  = 0.0f;
            rewardFunds       = 0.0f;
            failureReputation = 0.0f;
            failureFunds      = 0.0f;
            advanceFunds      = 0.0f;
            enabled           = true;
        }
Example #6
0
        public override void OnLoad(ConfigNode node)
        {
            try
            {
                lastMCButton            = ConfigNodeUtil.ParseValue <MissionControlButton>(node, "lastMCButton", MissionControlButton.All);
                DisplayOfferedOrbits    = ConfigNodeUtil.ParseValue <bool?>(node, "DisplayOfferedOrbits", (bool?)ContractDefs.DisplayOfferedOrbits).Value;
                DisplayOfferedWaypoints = ConfigNodeUtil.ParseValue <bool?>(node, "DisplayOfferedWaypoints", (bool?)ContractDefs.DisplayOfferedWaypoints).Value;
                DisplayActiveOrbits     = ConfigNodeUtil.ParseValue <bool?>(node, "DisplayActiveOrbits", (bool?)true).Value;
                DisplayActiveWaypoints  = ConfigNodeUtil.ParseValue <bool?>(node, "DisplayActiveWaypoints", (bool?)true).Value;

                foreach (ConfigNode groupNode in node.GetNodes("CONTRACT_GROUP"))
                {
                    string groupName = groupNode.GetValue("group");

                    if (ContractGroup.contractGroups.ContainsKey(groupName))
                    {
                        ContractGroup group = ContractGroup.contractGroups[groupName];

                        ContractGroupDetails details = new ContractGroupDetails(group);
                        details.enabled = ConfigNodeUtil.ParseValue <bool>(groupNode, "enabled");

                        contractGroupDetails[group.name] = details;
                    }
                    else
                    {
                        LoggingUtil.LogWarning(this, "Couldn't find contract group with name '" + groupName + "'");
                    }
                }

                foreach (ConfigNode stateNode in node.GetNodes("CONTRACT_STATE"))
                {
                    string typeName = stateNode.GetValue("type");
                    if (!string.IsNullOrEmpty(typeName))
                    {
                        Type contractType = null;
                        try
                        {
                            contractType = ConfigNodeUtil.ParseTypeValue(typeName);
                            StockContractDetails details = new StockContractDetails(contractType);
                            details.enabled = ConfigNodeUtil.ParseValue <bool>(stateNode, "enabled");

                            stockContractDetails[contractType] = details;

                            ContractDisabler.SetContractState(contractType, details.enabled);
                        }
                        catch (ArgumentException)
                        {
                            LoggingUtil.LogWarning(this, "Couldn't find contract type with name '" + typeName + "'");
                        }
                    }
                }
            }
            catch (Exception e)
            {
                LoggingUtil.LogError(this, "Error loading ContractConfiguratorSettings from persistance file!");
                LoggingUtil.LogException(e);
                ExceptionLogWindow.DisplayFatalException(ExceptionLogWindow.ExceptionSituation.SCENARIO_MODULE_LOAD, e, "ContractConfiguratorSettings");
            }
        }
 public static bool IsEnabled(ContractGroup group)
 {
     string identifier = group == null ? "" : group.name;
     if (Instance != null && Instance.contractGroupDetails.ContainsKey(identifier))
     {
         return Instance.contractGroupDetails[identifier].enabled;
     }
     return true;
 }
Example #8
0
        public static bool IsEnabled(ContractGroup group)
        {
            string identifier = group == null ? "" : group.name;

            if (Instance != null && Instance.contractGroupDetails.ContainsKey(identifier))
            {
                return(Instance.contractGroupDetails[identifier].enabled);
            }
            return(true);
        }
        /// <summary>
        /// Loads all the contact configuration group nodes.
        /// </summary>
        private IEnumerator <YieldInstruction> LoadGroupConfig()
        {
            // Load all the contract groups
            LoggingUtil.LogDebug(this, "Loading CONTRACT_GROUP nodes.");
            ConfigNode[] contractGroups = GameDatabase.Instance.GetConfigNodes("CONTRACT_GROUP");

            foreach (ConfigNode groupConfig in contractGroups)
            {
                // Create the group
                string name = groupConfig.GetValue("name");
                LoggingUtil.LogInfo(this, "Loading CONTRACT_GROUP: '" + name + "'");
                ContractGroup contractGroup = null;
                try
                {
                    contractGroup = new ContractGroup(name);
                }
                catch (ArgumentException)
                {
                    LoggingUtil.LogError(this, "Couldn't load CONTRACT_GROUP '" + name + "' due to a duplicate name.");
                }

                // Peform the actual load
                if (contractGroup != null)
                {
                    bool success = false;
                    try
                    {
                        ConfigNodeUtil.ClearCache(true);
                        success = contractGroup.Load(groupConfig);
                    }
                    catch (Exception e)
                    {
                        Exception wrapper = new Exception("Error loading CONTRACT_GROUP '" + name + "'", e);
                        LoggingUtil.LogException(wrapper);
                    }
                    finally
                    {
                        if (!success)
                        {
                            ContractGroup.contractGroups.Remove(name);
                        }
                    }
                }
            }

            if (!reloading)
            {
                yield return(new WaitForEndOfFrame());
            }

            // Emit settings for the menu
            SettingsBuilder.EmitSettings();

            yield break;
        }
 protected IEnumerable<ContractGroup> ChildGroups(ContractGroup group)
 {
     foreach (ContractGroup child in ContractGroup.AllGroups.Where(g => g != null && g.parent == group))
     {
         yield return child;
         foreach (ContractGroup descendent in ChildGroups(child))
         {
             yield return descendent;
         }
     }
 }
        /// <summary>
        /// Static method (used by other mods via reflection) to get the contract group display name.
        /// </summary>
        public static string GroupDisplayName(string groupName)
        {
            if (string.IsNullOrEmpty(groupName))
            {
                return("");
            }

            ContractGroup group = contractGroups.ContainsKey(groupName) ? contractGroups[groupName] : null;

            return(group == null ? "" : group.displayName);
        }
Example #12
0
        private void ContractGroupLine(ContractGroup contractGroup, int indent = 0)
        {
            string identifier = contractGroup == null ? "" : contractGroup.name;

            if (!contractGroupDetails.ContainsKey(identifier))
            {
                contractGroupDetails[identifier] = new ContractGroupDetails(contractGroup);
            }
            ContractGroupDetails details = contractGroupDetails[identifier];

            GUILayout.BeginHorizontal();

            GUILayout.Label("", contractRegularText, GUILayout.ExpandWidth(false), GUILayout.Width((indent + 1) * 16));

            string groupName = contractGroup == null ? "No Group" : contractGroup.displayName;

            GUILayout.Label(groupName, details.enabled ? contractRegularText : contractDisabledText, GUILayout.ExpandWidth(true));
            if (contractGroup != null && contractGroup.parent == null)
            {
                bool enabled = GUILayout.Toggle(details.enabled,
                                                new GUIContent("", "Click to " + (details.enabled ? "disable " : "enable ") + contractGroup.displayName + " contracts."),
                                                contractToggleStyle, GUILayout.ExpandWidth(false));

                if (enabled != details.enabled)
                {
                    details.enabled = enabled;
                    if (enabled)
                    {
                        foreach (KeyValuePair <Type, StockContractDetails> pair in stockContractDetails.
                                 Where(p => ContractDisabler.DisablingGroups(p.Key).Contains(contractGroup)))
                        {
                            pair.Value.enabled = false;
                            ContractDisabler.SetContractState(pair.Key, false);
                        }
                    }
                    else
                    {
                        foreach (KeyValuePair <Type, StockContractDetails> pair in stockContractDetails.
                                 Where(p => ContractDisabler.DisablingGroups(p.Key).Contains(contractGroup) &&
                                       ContractDisabler.DisablingGroups(p.Key).All(g => !IsEnabled(g))))
                        {
                            pair.Value.enabled = true;
                            ContractDisabler.SetContractState(pair.Key, true);
                        }
                    }
                }
            }
            GUILayout.EndHorizontal();
        }
        public static void SetContractToDisabled(string contract, ContractGroup group)
        {
            Type contractType = contractTypes.Where(t => t.Name == contract).FirstOrDefault();
            if (contractType == null)
            {
                LoggingUtil.LogWarning(typeof(ContractDisabler), "Couldn't find ContractType '" + contract + "' to disable.");
            }

            if (!contractDetails.ContainsKey(contractType))
            {
                contractDetails[contractType] = new ContractDetails(contractType);
            }
            ContractDetails details = contractDetails[contractType];

            details.disablingGroups.AddUnique(group);
            SetContractState(contractType, false);
        }
Example #14
0
        public static void SetContractToDisabled(string contract, ContractGroup group)
        {
            Type contractType = contractTypes.Where(t => t.Name == contract).FirstOrDefault();

            if (contractType == null)
            {
                LoggingUtil.LogWarning(typeof(ContractDisabler), "Couldn't find ContractType '" + contract + "' to disable.");
            }

            if (!contractDetails.ContainsKey(contractType))
            {
                contractDetails[contractType] = new ContractDetails(contractType);
            }
            ContractDetails details = contractDetails[contractType];

            details.disablingGroups.AddUnique(group);
            SetContractState(contractType, false);
        }
        /// <summary>
        /// Checks if the given contract type belongs to the given group
        /// </summary>
        /// <param name="contractType">The contract type to check</param>
        /// <returns>True if the contract type is a part of this group</returns>
        public bool BelongsToGroup(ContractType contractType)
        {
            if (contractType == null)
            {
                return(false);
            }

            ContractGroup group = contractType.group;

            while (group != null)
            {
                if (group.name == name)
                {
                    return(true);
                }
                group = group.parent;
            }

            return(false);
        }
        /// <summary>
        /// Loads the contract group details from the given config node.
        /// </summary>
        /// <param name="configNode">The config node to load from</param>
        /// <returns>Whether we were successful.</returns>
        public bool Load(ConfigNode configNode)
        {
            try
            {
                dataNode = new DataNode(configNode.GetValue("name"), this);

                LoggingUtil.CaptureLog = true;
                ConfigNodeUtil.SetCurrentDataNode(dataNode);
                bool valid = true;

                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "name", x => name = x, this);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "displayName", x => displayName = x, this, name);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "minVersion", x => minVersion = x, this, "");
                valid &= ConfigNodeUtil.ParseValue<int>(configNode, "maxCompletions", x => maxCompletions = x, this, 0, x => Validation.GE(x, 0));
                valid &= ConfigNodeUtil.ParseValue<int>(configNode, "maxSimultaneous", x => maxSimultaneous = x, this, 0, x => Validation.GE(x, 0));
                valid &= ConfigNodeUtil.ParseValue<List<string>>(configNode, "disabledContractType", x => disabledContractType = x, this, new List<string>());

                if (!string.IsNullOrEmpty(minVersion))
                {
                    if (Util.Version.VerifyAssemblyVersion("ContractConfigurator", minVersion) == null)
                    {
                        valid = false;

                        var ainfoV = Attribute.GetCustomAttribute(typeof(ExceptionLogWindow).Assembly, typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute;
                        string title = "Contract Configurator " + ainfoV.InformationalVersion + " Message";
                        string message = "The contract group '" + name + "' requires at least Contract Configurator " + minVersion +
                            " to work, and you are running version " + ainfoV.InformationalVersion +
                            ".  Please upgrade Contract Configurator to use the contracts in this group.";
                        DialogOption dialogOption = new DialogOption("Okay", new Callback(DoNothing), true);
                        PopupDialog.SpawnPopupDialog(new MultiOptionDialog(message, title, HighLogic.Skin, dialogOption), false, HighLogic.Skin);
                    }
                }

                // Load DATA nodes
                valid &= dataNode.ParseDataNodes(configNode, this, dataValues, uniquenessChecks);

                // Do the deferred loads
                valid &= ConfigNodeUtil.ExecuteDeferredLoads();

                config = configNode.ToString();
                log += LoggingUtil.capturedLog;
                LoggingUtil.CaptureLog = false;

                // Load child groups
                foreach (ConfigNode childNode in ConfigNodeUtil.GetChildNodes(configNode, "CONTRACT_GROUP"))
                {
                    ContractGroup child = null;
                    string childName = childNode.GetValue("name");
                    try
                    {
                        child = new ContractGroup(childName);
                    }
                    catch (ArgumentException)
                    {
                        LoggingUtil.LogError(this, "Couldn't load CONTRACT_GROUP '" + childName + "' due to a duplicate name.");
                        valid = false;
                        continue;
                    }

                    valid &= child.Load(childNode);
                    child.parent = this;
                    child.dataNode.Parent = dataNode;
                    if (child.hasWarnings)
                    {
                        hasWarnings = true;
                    }
                }

                // Check for unexpected values - always do this last
                valid &= ConfigNodeUtil.ValidateUnexpectedValues(configNode, this);

                // Invalidate children
                if (!valid)
                {
                    Invalidate();
                }

                enabled = valid;
                return valid;
            }
            catch
            {
                enabled = false;
                throw;
            }
        }
        /// <summary>
        /// Loads the contract group details from the given config node.
        /// </summary>
        /// <param name="configNode">The config node to load from</param>
        /// <returns>Whether we were successful.</returns>
        public bool Load(ConfigNode configNode)
        {
            try
            {
                dataNode = new DataNode(configNode.GetValue("name"), this);

                LoggingUtil.CaptureLog = true;
                ConfigNodeUtil.SetCurrentDataNode(dataNode);
                bool valid = true;

                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "name", x => name = x, this);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "displayName", x => displayName = x, this, name);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "minVersion", x => minVersionStr = x, this, "");
                valid &= ConfigNodeUtil.ParseValue <int>(configNode, "maxCompletions", x => maxCompletions = x, this, 0, x => Validation.GE(x, 0));
                valid &= ConfigNodeUtil.ParseValue <int>(configNode, "maxSimultaneous", x => maxSimultaneous = x, this, 0, x => Validation.GE(x, 0));
                valid &= ConfigNodeUtil.ParseValue <List <string> >(configNode, "disabledContractType", x => disabledContractType = x, this, new List <string>());
                valid &= ConfigNodeUtil.ParseValue <Agent>(configNode, "agent", x => agent = x, this, (Agent)null);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "sortKey", x => sortKey = x, this, displayName);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "tip", x => {}, this, "");

                if (configNode.HasValue("sortKey") && parent == null)
                {
                    sortKey = displayName;
                    LoggingUtil.LogWarning(this, ErrorPrefix() + ": Using the sortKey field is only applicable on child CONTRACT_GROUP elements");
                }

                if (!string.IsNullOrEmpty(minVersionStr))
                {
                    if (Util.Version.VerifyAssemblyVersion("ContractConfigurator", minVersionStr) == null)
                    {
                        valid = false;

                        var    ainfoV  = Attribute.GetCustomAttribute(typeof(ExceptionLogWindow).Assembly, typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute;
                        string title   = "Contract Configurator " + ainfoV.InformationalVersion + " Message";
                        string message = "The contract group '" + name + "' requires at least Contract Configurator " + minVersionStr +
                                         " to work, and you are running version " + ainfoV.InformationalVersion +
                                         ".  Please upgrade Contract Configurator to use the contracts in this group.";
                        DialogGUIButton dialogOption = new DialogGUIButton("Okay", new Callback(DoNothing), true);
                        PopupDialog.SpawnPopupDialog(new MultiOptionDialog(message, title, UISkinManager.GetSkin("default"), dialogOption), false, UISkinManager.GetSkin("default"));
                    }
                }

                // Load DATA nodes
                valid &= dataNode.ParseDataNodes(configNode, this, dataValues, uniquenessChecks);

                // Do the deferred loads
                valid &= ConfigNodeUtil.ExecuteDeferredLoads();

                // Do post-deferred load warnings
                if (agent == null)
                {
                    LoggingUtil.LogWarning(this, ErrorPrefix() + ": Providing the agent field for all CONTRACT_GROUP nodes is highly recommended, as the agent is used to group contracts in Mission Control.");
                }
                if (string.IsNullOrEmpty(minVersionStr) || minVersion < ContractConfigurator.ENHANCED_UI_VERSION)
                {
                    LoggingUtil.LogWarning(this, ErrorPrefix() + ": No minVersion or older minVersion provided.  It is recommended that the minVersion is set to at least 1.15.0 to turn important warnings for deprecated functionality into errors.");
                }
                if (!configNode.HasValue("displayName"))
                {
                    LoggingUtil.LogWarning(this, ErrorPrefix() + ": No display name provided.  A display name is recommended, as it is used in the Mission Control UI.");
                }

                config = configNode.ToString();
                log   += LoggingUtil.capturedLog;
                LoggingUtil.CaptureLog = false;

                // Load child groups
                foreach (ConfigNode childNode in ConfigNodeUtil.GetChildNodes(configNode, "CONTRACT_GROUP"))
                {
                    ContractGroup child     = null;
                    string        childName = childNode.GetValue("name");
                    try
                    {
                        child = new ContractGroup(childName);
                    }
                    catch (ArgumentException)
                    {
                        LoggingUtil.LogError(this, "Couldn't load CONTRACT_GROUP '" + childName + "' due to a duplicate name.");
                        valid = false;
                        continue;
                    }

                    child.parent          = this;
                    valid                &= child.Load(childNode);
                    child.dataNode.Parent = dataNode;
                    if (child.hasWarnings)
                    {
                        hasWarnings = true;
                    }
                }

                // Check for unexpected values - always do this last
                valid &= ConfigNodeUtil.ValidateUnexpectedValues(configNode, this);

                // Invalidate children
                if (!valid)
                {
                    Invalidate();
                }

                enabled = valid;
                return(valid);
            }
            catch
            {
                enabled = false;
                throw;
            }
        }
Example #18
0
        /// <summary>
        /// Loads the contract type details from the given config node.
        /// </summary>
        /// <param name="configNode">The config node to load from.</param>
        /// <returns>Whether the load was successful.</returns>
        public bool Load(ConfigNode configNode)
        {
            try
            {
                // Logging on
                LoggingUtil.CaptureLog = true;

                dataNode = new DataNode(configNode.GetValue("name"), this);

                ConfigNodeUtil.ClearCache(true);
                ConfigNodeUtil.SetCurrentDataNode(dataNode);
                bool valid = true;

                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "name", x => name = x, this);

                // Load contract text details
                valid &= ConfigNodeUtil.ParseValue <ContractGroup>(configNode, "group", x => group = x, this, (ContractGroup)null);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "title", x => title = x, this);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "tag", x => tag = x, this, "");
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "description", x => description = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "topic", x => topic = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "subject", x => subject = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "motivation", x => motivation = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "notes", x => notes = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "synopsis", x => synopsis = x, this);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "completedMessage", x => completedMessage = x, this);

                // Load optional attributes
                valid &= ConfigNodeUtil.ParseValue <Agent>(configNode, "agent", x => agent = x, this, (Agent)null);
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "minExpiry", x => minExpiry = x, this, 1.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "maxExpiry", x => maxExpiry = x, this, 7.0f, x => Validation.GE(x, minExpiry));
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "deadline", x => deadline = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue <bool>(configNode, "cancellable", x => cancellable = x, this, true);
                valid &= ConfigNodeUtil.ParseValue <bool>(configNode, "declinable", x => declinable = x, this, true);
                valid &= ConfigNodeUtil.ParseValue <List <Contract.ContractPrestige> >(configNode, "prestige", x => prestige = x, this, new List <Contract.ContractPrestige>());
                valid &= ConfigNodeUtil.ParseValue <CelestialBody>(configNode, "targetBody", x => targetBody = x, this, (CelestialBody)null);

                valid &= ConfigNodeUtil.ParseValue <int>(configNode, "maxCompletions", x => maxCompletions = x, this, 0, x => Validation.GE(x, 0));
                valid &= ConfigNodeUtil.ParseValue <int>(configNode, "maxSimultaneous", x => maxSimultaneous = x, this, 0, x => Validation.GE(x, 0));

                // Load rewards
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "rewardFunds", x => rewardFunds = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "rewardReputation", x => rewardReputation = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "rewardScience", x => rewardScience = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "failureFunds", x => failureFunds = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "failureReputation", x => failureReputation = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "advanceFunds", x => advanceFunds = x, this, 0.0f, x => Validation.GE(x, 0.0f));

                // Load other values
                valid &= ConfigNodeUtil.ParseValue <double>(configNode, "weight", x => weight = x, this, 1.0, x => Validation.GE(x, 0.0f));

                // TODO - these are to be deprecated
                if (configNode.HasValue("targetBodies"))
                {
                    valid &= ConfigNodeUtil.ParseValue <List <CelestialBody> >(configNode, "targetBodies", x => targetBodies = x, this, new List <CelestialBody>());
                    LoggingUtil.LogWarning(this, "The 'targetBodies' attribute is obsolete as of Contract Configurator 0.7.4.  It will be removed in 1.0.0 in favour of the DATA { } node.");
                }
                if (configNode.HasValue("targetVessel"))
                {
                    valid &= ConfigNodeUtil.ParseValue <Vessel>(configNode, "targetVessel", x => targetVessel = x, this, (Vessel)null);
                    LoggingUtil.LogWarning(this, "The 'targetVessel' attribute is obsolete as of Contract Configurator 0.7.4.  It will be removed in 1.0.0 in favour of the DATA { } node.");
                }
                if (configNode.HasValue("targetVessels"))
                {
                    valid &= ConfigNodeUtil.ParseValue <List <Vessel> >(configNode, "targetVessels", x => targetVessels = x, this, new List <Vessel>());
                    LoggingUtil.LogWarning(this, "The 'targetVessels' attribute is obsolete as of Contract Configurator 0.7.4.  It will be removed in 1.0.0 in favour of the DATA { } node.");
                }
                if (configNode.HasValue("targetKerbal"))
                {
                    valid &= ConfigNodeUtil.ParseValue <Kerbal>(configNode, "targetKerbal", x => targetKerbal = x, this, (Kerbal)null);
                    LoggingUtil.LogWarning(this, "The 'targetKerbal' attribute is obsolete as of Contract Configurator 0.7.4.  It will be removed in 1.0.0 in favour of the DATA { } node.");
                }
                if (configNode.HasValue("targetKerbals"))
                {
                    valid &= ConfigNodeUtil.ParseValue <List <Kerbal> >(configNode, "targetKerbals", x => targetKerbals = x, this, new List <Kerbal>());
                    LoggingUtil.LogWarning(this, "The 'targetKerbals' attribute is obsolete as of Contract Configurator 0.7.4.  It will be removed in 1.0.0 in favour of the DATA { } node.");
                }

                // Load DATA nodes
                foreach (ConfigNode data in ConfigNodeUtil.GetChildNodes(configNode, "DATA"))
                {
                    Type type          = null;
                    bool requiredValue = true;
                    valid &= ConfigNodeUtil.ParseValue <Type>(data, "type", x => type = x, this);
                    valid &= ConfigNodeUtil.ParseValue <bool>(data, "requiredValue", x => requiredValue = x, this, true);

                    if (type != null)
                    {
                        foreach (ConfigNode.Value pair in data.values)
                        {
                            string name = pair.name;
                            if (name != "type" && name != "requiredValue")
                            {
                                object value = null;

                                // Create the setter function
                                Type     actionType = typeof(Action <>).MakeGenericType(type);
                                Delegate del        = Delegate.CreateDelegate(actionType, value, typeof(ContractType).GetMethod("NullAction"));

                                // Get the ParseValue method
                                MethodInfo method = typeof(ConfigNodeUtil).GetMethods(BindingFlags.Static | BindingFlags.Public).
                                                    Where(m => m.Name == "ParseValue" && m.GetParameters().Count() == 4).Single();
                                method = method.MakeGenericMethod(new Type[] { type });

                                // Invoke the ParseValue method
                                valid &= (bool)method.Invoke(null, new object[] { data, name, del, this });

                                dataValues[name] = requiredValue;
                            }
                        }
                    }
                }

                // Check for unexpected values - always do this last
                valid &= ConfigNodeUtil.ValidateUnexpectedValues(configNode, this);

                log = LoggingUtil.capturedLog;
                LoggingUtil.CaptureLog = false;

                // Load parameters
                foreach (ConfigNode contractParameter in ConfigNodeUtil.GetChildNodes(configNode, "PARAMETER"))
                {
                    ParameterFactory paramFactory = null;
                    valid &= ParameterFactory.GenerateParameterFactory(contractParameter, this, out paramFactory);
                    if (paramFactory != null)
                    {
                        paramFactories.Add(paramFactory);
                        if (paramFactory.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Load behaviours
                foreach (ConfigNode requirementNode in ConfigNodeUtil.GetChildNodes(configNode, "BEHAVIOUR"))
                {
                    BehaviourFactory behaviourFactory = null;
                    valid &= BehaviourFactory.GenerateBehaviourFactory(requirementNode, this, out behaviourFactory);
                    if (behaviourFactory != null)
                    {
                        behaviourFactories.Add(behaviourFactory);
                        if (behaviourFactory.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Load requirements
                foreach (ConfigNode requirementNode in ConfigNodeUtil.GetChildNodes(configNode, "REQUIREMENT"))
                {
                    ContractRequirement requirement = null;
                    valid &= ContractRequirement.GenerateRequirement(requirementNode, this, out requirement);
                    if (requirement != null)
                    {
                        requirements.Add(requirement);
                        if (requirement.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Logging on
                LoggingUtil.CaptureLog = true;

                // Check we have at least one valid parameter
                if (paramFactories.Count() == 0)
                {
                    LoggingUtil.LogError(this.GetType(), ErrorPrefix() + ": Need at least one parameter for a contract!");
                    valid = false;
                }

                // Do the deferred loads
                valid &= ConfigNodeUtil.ExecuteDeferredLoads();

                config  = configNode.ToString();
                hash    = config.GetHashCode();
                enabled = valid;
                log    += LoggingUtil.capturedLog;
                LoggingUtil.CaptureLog = false;

                return(valid);
            }
            catch
            {
                enabled = false;
                throw;
            }
        }
        /// <summary>
        /// Loads the contract type details from the given config node.
        /// </summary>
        /// <param name="configNode">The config node to load from.</param>
        /// <returns>Whether the load was successful.</returns>
        public bool Load(ConfigNode configNode)
        {
            LoggingUtil.LogLevel origLogLevel = LoggingUtil.logLevel;

            try
            {
                // Logging on
                LoggingUtil.CaptureLog = true;
                ConfigNodeUtil.SetCurrentDataNode(null);

                // Load values that are immediately required
                bool valid = true;
                valid &= ConfigNodeUtil.ParseValue<ContractGroup>(configNode, "group", x => group = x, this, (ContractGroup)null);

                // Set up the data node
                dataNode = new DataNode(configNode.GetValue("name"), group != null ? group.dataNode : null, this);
                ConfigNodeUtil.SetCurrentDataNode(dataNode);

                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "name", x => name = x, this);

                // Try to turn on trace mode
                valid &= ConfigNodeUtil.ParseValue<bool>(configNode, "trace", x => trace = x, this, false);
                if (trace)
                {
                    LoggingUtil.logLevel = LoggingUtil.LogLevel.VERBOSE;
                    LoggingUtil.LogWarning(this, "Tracing enabled for contract type " + name);
                }

                // Load contract text details
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "title", x => title = x, this);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "tag", x => tag = x, this, "");
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "description", x => description = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "topic", x => topic = x, this, "");
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "subject", x => subject = x, this, "");
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "motivation", x => motivation = x, this, "");
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "notes", x => notes = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "synopsis", x => synopsis = x, this);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "completedMessage", x => completedMessage = x, this);

                // Load optional attributes
                valid &= ConfigNodeUtil.ParseValue<Agent>(configNode, "agent", x => agent = x, this, (Agent)null);
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "minExpiry", x => minExpiry = x, this, 1.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "maxExpiry", x => maxExpiry = x, this, 7.0f, x => Validation.GE(x, minExpiry));
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "deadline", x => deadline = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue<bool>(configNode, "cancellable", x => cancellable = x, this, true);
                valid &= ConfigNodeUtil.ParseValue<bool>(configNode, "declinable", x => declinable = x, this, true);
                valid &= ConfigNodeUtil.ParseValue<bool>(configNode, "autoAccept", x => autoAccept = x, this, false);
                valid &= ConfigNodeUtil.ParseValue<List<Contract.ContractPrestige>>(configNode, "prestige", x => prestige = x, this, new List<Contract.ContractPrestige>());
                valid &= ConfigNodeUtil.ParseValue<CelestialBody>(configNode, "targetBody", x => targetBody = x, this, (CelestialBody)null);
            
                valid &= ConfigNodeUtil.ParseValue<int>(configNode, "maxCompletions", x => maxCompletions = x, this, 0, x => Validation.GE(x, 0));
                valid &= ConfigNodeUtil.ParseValue<int>(configNode, "maxSimultaneous", x => maxSimultaneous = x, this, 0, x => Validation.GE(x, 0));

                // Load rewards
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "rewardFunds", x => rewardFunds = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "rewardReputation", x => rewardReputation = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "rewardScience", x => rewardScience = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "failureFunds", x => failureFunds = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "failureReputation", x => failureReputation = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "advanceFunds", x => advanceFunds = x, this, 0.0f, x => Validation.GE(x, 0.0f));

                // Load other values
                valid &= ConfigNodeUtil.ParseValue<double>(configNode, "weight", x => weight = x, this, 1.0, x => Validation.GE(x, 0.0f));

                // Merge in data from the parent contract group
                for (ContractGroup currentGroup = group; currentGroup != null; currentGroup = currentGroup.parent)
                {
                    // Merge dataValues - this is a flag saying what values need to be unique at the contract level
                    foreach (KeyValuePair<string, bool> pair in currentGroup.dataValues)
                    {
                        dataValues[group.name + ":" + pair.Key] = pair.Value;
                    }

                    // Merge uniquenessChecks
                    foreach (KeyValuePair<string, DataNode.UniquenessCheck> pair in currentGroup.uniquenessChecks)
                    {
                        uniquenessChecks[group.name + ":" + pair.Key] = pair.Value;
                    }
                }

                // Load DATA nodes
                valid &= dataNode.ParseDataNodes(configNode, this, dataValues, uniquenessChecks);

                // Check for unexpected values - always do this last
                valid &= ConfigNodeUtil.ValidateUnexpectedValues(configNode, this);

                log = LoggingUtil.capturedLog;
                LoggingUtil.CaptureLog = false;

                // Load parameters
                foreach (ConfigNode contractParameter in ConfigNodeUtil.GetChildNodes(configNode, "PARAMETER"))
                {
                    ParameterFactory paramFactory = null;
                    valid &= ParameterFactory.GenerateParameterFactory(contractParameter, this, out paramFactory);
                    if (paramFactory != null)
                    {
                        paramFactories.Add(paramFactory);
                        if (paramFactory.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Load behaviours
                foreach (ConfigNode requirementNode in ConfigNodeUtil.GetChildNodes(configNode, "BEHAVIOUR"))
                {
                    BehaviourFactory behaviourFactory = null;
                    valid &= BehaviourFactory.GenerateBehaviourFactory(requirementNode, this, out behaviourFactory);
                    if (behaviourFactory != null)
                    {
                        behaviourFactories.Add(behaviourFactory);
                        if (behaviourFactory.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Load requirements
                foreach (ConfigNode requirementNode in ConfigNodeUtil.GetChildNodes(configNode, "REQUIREMENT"))
                {
                    ContractRequirement requirement = null;
                    valid &= ContractRequirement.GenerateRequirement(requirementNode, this, out requirement);
                    if (requirement != null)
                    {
                        requirements.Add(requirement);
                        if (requirement.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Logging on
                LoggingUtil.CaptureLog = true;

                // Check we have at least one valid parameter
                if (paramFactories.Count() == 0)
                {
                    LoggingUtil.LogError(this.GetType(), ErrorPrefix() + ": Need at least one parameter for a contract!");
                    valid = false;
                }

                // Do the deferred loads
                valid &= ConfigNodeUtil.ExecuteDeferredLoads();

                config = configNode.ToString();
                hash = config.GetHashCode();
                enabled = valid;
                log += LoggingUtil.capturedLog;

				if (LoggingUtil.logLevel == LoggingUtil.LogLevel.VERBOSE || LoggingUtil.logLevel == LoggingUtil.LogLevel.DEBUG)
				{
					//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
					// to write the complete config and log for contract to both the system log and
					// a seperate CC log file
					//
					string pattern = @"\[(VERBOSE|DEBUG|INFO|WARNING|ERROR)\] ContractConfigurator\.ExpressionParser.BaseParser.+\n";
					string replacement = "";
					Regex rgx = new Regex(pattern);

					// First, write to the standard log file.  the regex strips out the leading text of the line, but 
					// if you want the text there, then just remove the rgx.Replace
					LoggingUtil.LogDebug(this, config);
					// Write the log out, ignoring the BaseParser lines
					LoggingUtil.LogDebug(this, rgx.Replace(log, replacement));

					// Now write to the CC log file, in a much cleaner manner 
					string path = ccLogFile;

					// Delete the file first time through, ignore any errors
					if (deleteCCLogfile)
					{
						deleteCCLogfile = false;
						try {
							if (File.Exists(path))
								File.Delete(path);
						} catch { 
							LoggingUtil.LogError(this, "Exception while attempting to delete the file: " + path);
						}
					}
					// Create the file if it doesn't exist
					if (!File.Exists(path)) 
					{
						// Create a file to write to.
						try {
							using (StreamWriter sw = File.CreateText(path)) {}
						} catch {
							LoggingUtil.LogError(this, "Exception while attempting to create the file: " + path);
						}
					}

					// This regex also strips out the second part of the line, so that the output is very clean 

					string pattern2 = @"\[(VERBOSE|DEBUG|INFO|WARNING|ERROR)\] ContractConfigurator\.ExpressionParser\.DataNode: ";
					Regex rgx2 = new Regex(pattern2);

					// Now write the config and the cleaned up log to it
					try {
						using (StreamWriter sw = File.AppendText (path)) {
							sw.WriteLine (config);
							sw.WriteLine("++++++++++\n");
							sw.WriteLine(rgx2.Replace(rgx.Replace(log, replacement), replacement));
							sw.WriteLine("==================================================================================");
	        		    }
					} catch {
						LoggingUtil.LogError(this, "Exception while attempting to write to the file: " + path);
					}
					//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
				}
				LoggingUtil.CaptureLog = false;

				return valid;
			}
            catch
            {
                enabled = false;
                throw;
            }
            finally
            {
                LoggingUtil.logLevel = origLogLevel;
                loaded = true;
            }
        }
        /// <summary>
        /// Loads the contract group details from the given config node.
        /// </summary>
        /// <param name="configNode">The config node to load from</param>
        /// <returns>Whether we were successful.</returns>
        public bool Load(ConfigNode configNode)
        {
            try
            {
                dataNode = new DataNode(configNode.GetValue("name"), this);

                LoggingUtil.CaptureLog = true;
                ConfigNodeUtil.ClearCache(true);
                ConfigNodeUtil.SetCurrentDataNode(dataNode);
                bool valid = true;

                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "name", x => name = x, this);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "minVersion", x => minVersion = x, this, "");
                valid &= ConfigNodeUtil.ParseValue <int>(configNode, "maxCompletions", x => maxCompletions = x, this, 0, x => Validation.GE(x, 0));
                valid &= ConfigNodeUtil.ParseValue <int>(configNode, "maxSimultaneous", x => maxSimultaneous = x, this, 0, x => Validation.GE(x, 0));

                if (!string.IsNullOrEmpty(minVersion))
                {
                    if (Util.Version.VerifyAssemblyVersion("ContractConfigurator", minVersion) == null)
                    {
                        valid = false;

                        var    ainfoV  = Attribute.GetCustomAttribute(typeof(ExceptionLogWindow).Assembly, typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute;
                        string title   = "Contract Configurator " + ainfoV.InformationalVersion + " Message";
                        string message = "The contract group '" + name + "' requires at least Contract Configurator " + minVersion +
                                         " to work, and you are running version " + ainfoV.InformationalVersion +
                                         ".  Please upgrade Contract Configurator to use the contracts in this group.";
                        DialogOption dialogOption = new DialogOption("Okay", new Callback(DoNothing), true);
                        PopupDialog.SpawnPopupDialog(new MultiOptionDialog(message, title, HighLogic.Skin, dialogOption), false, HighLogic.Skin);
                    }
                }

                // Check for unexpected values - always do this last
                valid &= ConfigNodeUtil.ValidateUnexpectedValues(configNode, this);

                // Do the deferred loads
                valid &= ConfigNodeUtil.ExecuteDeferredLoads();

                config = configNode.ToString();
                log   += LoggingUtil.capturedLog;
                LoggingUtil.CaptureLog = false;

                // Load child groups
                foreach (ConfigNode childNode in ConfigNodeUtil.GetChildNodes(configNode, "CONTRACT_GROUP"))
                {
                    ContractGroup child = null;
                    string        name  = childNode.GetValue("name");
                    try
                    {
                        child = new ContractGroup(name);
                    }
                    catch (ArgumentException)
                    {
                        LoggingUtil.LogError(this, "Couldn't load CONTRACT_GROUP '" + name + "' due to a duplicate name.");
                        valid = false;
                        continue;
                    }

                    valid       &= child.Load(childNode);
                    child.parent = this;
                    if (child.hasWarnings)
                    {
                        hasWarnings = true;
                    }
                }

                // Invalidate children
                if (!valid)
                {
                    Invalidate();
                }

                enabled = valid;
                return(valid);
            }
            catch
            {
                enabled = false;
                throw;
            }
        }
Example #21
0
        /// <summary>
        /// Loads all the contact configuration nodes and creates ContractType objects.
        /// </summary>
        private IEnumerator <YieldInstruction> LoadContractConfig()
        {
            // Load all the contract groups
            LoggingUtil.LogDebug(this.GetType(), "Loading CONTRACT_GROUP nodes.");
            ConfigNode[] contractGroups = GameDatabase.Instance.GetConfigNodes("CONTRACT_GROUP");

            foreach (ConfigNode groupConfig in contractGroups)
            {
                // Create the group
                string name = groupConfig.GetValue("name");
                LoggingUtil.LogInfo(this.GetType(), "Loading CONTRACT_GROUP: '" + name + "'");
                ContractGroup contractGroup = null;
                try
                {
                    contractGroup = new ContractGroup(name);
                }
                catch (ArgumentException)
                {
                    LoggingUtil.LogError(this.GetType(), "Couldn't load CONTRACT_GROUP '" + name + "' due to a duplicate name.");
                }

                // Peform the actual load
                if (contractGroup != null)
                {
                    bool success = false;
                    try
                    {
                        success = contractGroup.Load(groupConfig);
                    }
                    catch (Exception e)
                    {
                        Exception wrapper = new Exception("Error loading CONTRACT_GROUP '" + name + "'", e);
                        LoggingUtil.LogException(wrapper);
                    }
                    finally
                    {
                        if (!success)
                        {
                            ContractGroup.contractGroups.Remove(name);
                        }
                    }
                }
            }

            LoggingUtil.LogDebug(this.GetType(), "Loading CONTRACT_TYPE nodes.");
            ConfigNode[] contractConfigs = GameDatabase.Instance.GetConfigNodes("CONTRACT_TYPE");
            totalContracts = contractConfigs.Count();

            // First pass - create all the ContractType objects
            foreach (ConfigNode contractConfig in contractConfigs)
            {
                // Create the initial contract type
                LoggingUtil.LogVerbose(this.GetType(), "Pre-load for node: '" + contractConfig.GetValue("name") + "'");
                try
                {
                    ContractType contractType = new ContractType(contractConfig.GetValue("name"));
                }
                catch (ArgumentException)
                {
                    LoggingUtil.LogError(this.GetType(), "Couldn't load CONTRACT_TYPE '" + contractConfig.GetValue("name") + "' due to a duplicate name.");
                }
            }

            // Second pass - do the actual loading of details
            foreach (ConfigNode contractConfig in contractConfigs)
            {
                attemptedContracts++;
                yield return(new WaitForEndOfFrame());

                // Fetch the contractType
                string       name         = contractConfig.GetValue("name");
                ContractType contractType = ContractType.GetContractType(name);
                if (contractType != null)
                {
                    LoggingUtil.LogDebug(this.GetType(), "Loading CONTRACT_TYPE: '" + name + "'");
                    // Perform the load
                    try
                    {
                        contractType.Load(contractConfig);
                        if (contractType.enabled)
                        {
                            successContracts++;
                        }
                    }
                    catch (Exception e)
                    {
                        Exception wrapper = new Exception("Error loading CONTRACT_TYPE '" + name + "'", e);
                        LoggingUtil.LogException(wrapper);
                    }
                }
            }

            LoggingUtil.LogInfo(this.GetType(), "Loaded " + successContracts + " out of " + totalContracts + " CONTRACT_TYPE nodes.");

            if (!reloading && LoggingUtil.logLevel == LoggingUtil.LogLevel.DEBUG || LoggingUtil.logLevel == LoggingUtil.LogLevel.VERBOSE)
            {
                ScreenMessages.PostScreenMessage("Contract Configurator: Loaded " + successContracts + " out of " + totalContracts
                                                 + " contracts successfully.", 5, ScreenMessageStyle.UPPER_CENTER);
            }
        }
        private static void GroupGui(ContractGroup contractGroup, int indent)
        {
            if (contractGroup != null)
            {
                GUILayout.BeginHorizontal();

                if (indent != 0)
                {
                    GUILayout.Label("", GUILayout.ExpandWidth(false), GUILayout.Width(indent * 16));
                }

                if (GUILayout.Button(contractGroup.expandInDebug ? "-" : "+", GUILayout.Width(20), GUILayout.Height(20)))
                {
                    contractGroup.expandInDebug = !contractGroup.expandInDebug;
                }

                GUIStyle style = greenLabel;
                if (!contractGroup.enabled)
                {
                    style = redLabel;
                }
                else
                {
                    if (contractGroup.hasWarnings)
                    {
                        style = yellowLabel;
                    }

                    foreach (ContractType contractType in guiContracts.Where(ct => contractGroup == null ? ct.group == null : contractGroup.BelongsToGroup(ct)))
                    {
                        if (!contractType.enabled)
                        {
                            style = redLabel;
                            break;
                        }
                        else if (contractType.hasWarnings)
                        {
                            style = yellowLabel;
                        }
                    }
                }

                GUILayout.Label(new GUIContent(contractGroup.ToString(), DebugInfo(contractGroup)), style);
                GUILayout.EndHorizontal();
            }

            if (contractGroup == null || contractGroup.expandInDebug)
            {
                // Child groups
                if (contractGroup != null)
                {
                    foreach (ContractGroup childGroup in ContractGroup.AllGroups.Where(g => g != null && g.parent != null && g.parent.name == contractGroup.name))
                    {
                        GroupGui(childGroup, indent + 1);
                    }
                }

                // Child contract types
                foreach (ContractType contractType in guiContracts.Where(ct => ct.group == contractGroup))
                {
                    GUILayout.BeginHorizontal();

                    if (contractGroup != null)
                    {
                        GUILayout.Label("", GUILayout.ExpandWidth(false), GUILayout.Width((indent+1) * 16));
                    }

                    if (GUILayout.Button(contractType.expandInDebug ? "-" : "+", GUILayout.Width(20), GUILayout.Height(20)))
                    {
                        contractType.expandInDebug = !contractType.expandInDebug;
                    }
                    GUILayout.Label(new GUIContent(contractType.ToString(), DebugInfo(contractType)),
                        contractType.enabled ? contractType.hasWarnings ? yellowLabel : GUI.skin.label : redLabel);
                    GUILayout.EndHorizontal();

                    if (contractType.expandInDebug)
                    {
                        // Output children
                        ParamGui(contractType, contractType.ParamFactories, indent + (contractGroup == null ? 1 : 2));
                        RequirementGui(contractType, contractType.Requirements, indent + (contractGroup == null ? 1 : 2));
                        BehaviourGui(contractType, contractType.BehaviourFactories, indent + (contractGroup == null ? 1 : 2));

                        GUILayout.Space(8);
                    }
                }
            }
        }
        private IEnumerable<ConfiguredContract> ContractGenerator(Contract.ContractPrestige prestige, ContractGroup group)
        {
            ConfiguredContract templateContract =
                Contract.Generate(typeof(ConfiguredContract), prestige, rand.Next(), Contract.State.Withdrawn) as ConfiguredContract;

            // Build a weighted list of ContractTypes to choose from
            Dictionary<ContractType, double> validContractTypes = new Dictionary<ContractType, double>();
            double totalWeight = 0.0;
            foreach (ContractType ct in ContractType.AllValidContractTypes.Where(ct => ct.group == group))
            {
                // Check if we're only looking at auto-accept contracts
                if (currentDetails != null && currentDetails.contracts.Count() >= MAX_CONTRACTS && !ct.autoAccept)
                {
                    continue;
                }

                // Only select contracts with the correct prestige level
                if (ct.prestige.Count == 0 || ct.prestige.Contains(prestige))
                {
                    validContractTypes.Add(ct, ct.weight);
                    totalWeight += ct.weight;
                }
            }

            // Loop until we either run out of contracts in our list or make a selection
            while (validContractTypes.Count > 0)
            {
                ContractType selectedContractType = null;
                // Pick one of the contract types based on their weight
                double value = rand.NextDouble() * totalWeight;
                foreach (KeyValuePair<ContractType, double> pair in validContractTypes)
                {
                    value -= pair.Value;
                    if (value <= 0.0)
                    {
                        selectedContractType = pair.Key;
                        break;
                    }
                }

                // Shouldn't happen, but floating point rounding could put us here
                if (selectedContractType == null)
                {
                    selectedContractType = validContractTypes.First().Key;
                }

                // First, check the basic requirements
                if (!selectedContractType.MeetBasicRequirements(templateContract))
                {
                    LoggingUtil.LogVerbose(this, selectedContractType.name + " was not generated: basic requirements not met.");
                    validContractTypes.Remove(selectedContractType);
                    totalWeight -= selectedContractType.weight;

                    yield return null;
                    continue;
                }

                // Try to refresh non-deterministic values before we check extended requirements
                OnInitializeValues.Fire();
                LoggingUtil.LogLevel origLogLevel = LoggingUtil.logLevel;
                LoggingUtil.LogLevel newLogLevel = selectedContractType.trace ? LoggingUtil.LogLevel.VERBOSE : LoggingUtil.logLevel;
                bool failure = false;
                try
                {
                    // Set up for loop
                    LoggingUtil.logLevel = newLogLevel;
                    ConfiguredContract.currentContract = templateContract;

                    // Set up the iterator to refresh non-deterministic values
                    IEnumerable<string> iter = ConfigNodeUtil.UpdateNonDeterministicValuesIterator(selectedContractType.dataNode);
                    for (ContractGroup g = selectedContractType.group; g != null; g = g.parent)
                    {
                        iter = ConfigNodeUtil.UpdateNonDeterministicValuesIterator(g.dataNode).Concat(iter);
                    }

                    // Update the actual values
                    LoggingUtil.LogVerbose(this, "Refresh non-deterministic values for CONTRACT_TYPE = " + selectedContractType.name);
                    foreach (string val in iter)
                    {
                        lastKey = selectedContractType.name + "[" + val + "]";

                        // Clear temp stuff
                        LoggingUtil.logLevel = origLogLevel;
                        ConfiguredContract.currentContract = null;

                        if (val == null)
                        {
                            LoggingUtil.LogVerbose(this, selectedContractType.name + " was not generated: non-deterministic expression failure.");
                            validContractTypes.Remove(selectedContractType);
                            totalWeight -= selectedContractType.weight;

                            yield return null;
                            failure = true;
                            break;
                        }
                        else
                        {
                            yield return null;
                        }

                        // Re set up
                        LoggingUtil.logLevel = newLogLevel;
                        ConfiguredContract.currentContract = templateContract;
                    }
                }
                finally
                {
                    LoggingUtil.logLevel = origLogLevel;
                    ConfiguredContract.currentContract = null;
                }

                if (failure)
                {
                    OnInitializeFail.Fire();
                    continue;
                }

                // Store unique data
                foreach (string key in selectedContractType.uniquenessChecks.Keys)
                {
                    templateContract.uniqueData[key] = selectedContractType.dataNode[key];
                }

                // Check the requirements for our selection
                if (selectedContractType.MeetExtendedRequirements(templateContract, selectedContractType) && templateContract.Initialize(selectedContractType))
                {
                    yield return templateContract;
                    yield break;
                }
                // Remove the selection, and try again
                else
                {
                    LoggingUtil.LogVerbose(this, selectedContractType.name + " was not generated: requirement not met.");
                    validContractTypes.Remove(selectedContractType);
                    totalWeight -= selectedContractType.weight;
                    templateContract.uniqueData.Clear();
                    templateContract.contractType = null;
                }

                // Take a pause
                OnInitializeFail.Fire();
                yield return null;
            }
        }
        /// <summary>
        /// Loads the contract group details from the given config node.
        /// </summary>
        /// <param name="configNode">The config node to load from</param>
        /// <returns>Whether we were successful.</returns>
        public bool Load(ConfigNode configNode)
        {
            try
            {
                dataNode = new DataNode(configNode.GetValue("name"), this);

                LoggingUtil.CaptureLog = true;
                ConfigNodeUtil.SetCurrentDataNode(dataNode);
                bool valid = true;
                string unused;

                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "name", x => name = x, this);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "displayName", x => displayName = x, this, name);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "minVersion", x => minVersionStr = x, this, "");
                valid &= ConfigNodeUtil.ParseValue<int>(configNode, "maxCompletions", x => maxCompletions = x, this, 0, x => Validation.GE(x, 0));
                valid &= ConfigNodeUtil.ParseValue<int>(configNode, "maxSimultaneous", x => maxSimultaneous = x, this, 0, x => Validation.GE(x, 0));
                valid &= ConfigNodeUtil.ParseValue<List<string>>(configNode, "disabledContractType", x => disabledContractType = x, this, new List<string>());
                valid &= ConfigNodeUtil.ParseValue<Agent>(configNode, "agent", x => agent = x, this, (Agent)null);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "sortKey", x => sortKey = x, this, displayName);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "tip", x => unused = x, this, "");

                if (configNode.HasValue("sortKey") && parent == null)
                {
                    sortKey = displayName;
                    LoggingUtil.LogWarning(this, ErrorPrefix() + ": Using the sortKey field is only applicable on child CONTRACT_GROUP elements");
                }

                if (!string.IsNullOrEmpty(minVersionStr))
                {
                    if (Util.Version.VerifyAssemblyVersion("ContractConfigurator", minVersionStr) == null)
                    {
                        valid = false;

                        var ainfoV = Attribute.GetCustomAttribute(typeof(ExceptionLogWindow).Assembly, typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute;
                        string title = "Contract Configurator " + ainfoV.InformationalVersion + " Message";
                        string message = "The contract group '" + name + "' requires at least Contract Configurator " + minVersionStr +
                            " to work, and you are running version " + ainfoV.InformationalVersion +
                            ".  Please upgrade Contract Configurator to use the contracts in this group.";
                        DialogGUIButton dialogOption = new DialogGUIButton("Okay", new Callback(DoNothing), true);
                        PopupDialog.SpawnPopupDialog(new MultiOptionDialog(message, title, UISkinManager.GetSkin("default"), dialogOption), false, UISkinManager.GetSkin("default"));
                    }
                }

                // Load DATA nodes
                valid &= dataNode.ParseDataNodes(configNode, this, dataValues, uniquenessChecks);

                // Do the deferred loads
                valid &= ConfigNodeUtil.ExecuteDeferredLoads();

                // Do post-deferred load warnings
                if (agent == null)
                {
                    LoggingUtil.LogWarning(this, ErrorPrefix() + ": Providing the agent field for all CONTRACT_GROUP nodes is highly recommended, as the agent is used to group contracts in Mission Control.");
                }
                if (string.IsNullOrEmpty(minVersionStr) || minVersion < ContractConfigurator.ENHANCED_UI_VERSION)
                {
                    LoggingUtil.LogWarning(this, ErrorPrefix() + ": No minVersion or older minVersion provided.  It is recommended that the minVersion is set to at least 1.15.0 to turn important warnings for deprecated functionality into errors.");
                }
                if (!configNode.HasValue("displayName"))
                {
                    LoggingUtil.LogWarning(this, ErrorPrefix() + ": No display name provided.  A display name is recommended, as it is used in the Mission Control UI.");
                }

                config = configNode.ToString();
                log += LoggingUtil.capturedLog;
                LoggingUtil.CaptureLog = false;

                // Load child groups
                foreach (ConfigNode childNode in ConfigNodeUtil.GetChildNodes(configNode, "CONTRACT_GROUP"))
                {
                    ContractGroup child = null;
                    string childName = childNode.GetValue("name");
                    try
                    {
                        child = new ContractGroup(childName);
                    }
                    catch (ArgumentException)
                    {
                        LoggingUtil.LogError(this, "Couldn't load CONTRACT_GROUP '" + childName + "' due to a duplicate name.");
                        valid = false;
                        continue;
                    }

                    child.parent = this;
                    valid &= child.Load(childNode);
                    child.dataNode.Parent = dataNode;
                    if (child.hasWarnings)
                    {
                        hasWarnings = true;
                    }
                }

                // Check for unexpected values - always do this last
                valid &= ConfigNodeUtil.ValidateUnexpectedValues(configNode, this);

                // Invalidate children
                if (!valid)
                {
                    Invalidate();
                }

                enabled = valid;
                return valid;
            }
            catch
            {
                enabled = false;
                throw;
            }
        }
Example #25
0
        /// <summary>
        /// Loads the contract type details from the given config node.
        /// </summary>
        /// <param name="configNode">The config node to load from.</param>
        /// <returns>Whether the load was successful.</returns>
        public bool Load(ConfigNode configNode)
        {
            LoggingUtil.LogLevel origLogLevel = LoggingUtil.logLevel;

            try
            {
                // Logging on
                LoggingUtil.CaptureLog = true;
                ConfigNodeUtil.SetCurrentDataNode(null);
                LoggingUtil.LogInfo(this, "Loading CONTRACT_TYPE: '" + name + "'");

                // Clear the config node cache
                ConfigNodeUtil.ClearCache(true);

                // Load values that are immediately required
                bool valid = true;
                valid &= ConfigNodeUtil.ParseValue <ContractGroup>(configNode, "group", x => group = x, this, (ContractGroup)null);

                // Set up the data node
                dataNode = new DataNode(configNode.GetValue("name"), group != null ? group.dataNode : null, this);
                ConfigNodeUtil.SetCurrentDataNode(dataNode);

                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "name", x => name = x, this);

                // Try to turn on trace mode
                valid &= ConfigNodeUtil.ParseValue <bool>(configNode, "trace", x => trace = x, this, false);
                if (trace)
                {
                    LoggingUtil.logLevel = LoggingUtil.LogLevel.VERBOSE;
                    LoggingUtil.LogWarning(this, "Tracing enabled for contract type " + name);
                }

                // Load contract text details
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "title", x => title = x, this);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "tag", x => tag = x, this, "");
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "description", x => description = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "topic", x => topic = x, this, "");
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "subject", x => subject = x, this, "");
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "notes", x => notes = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "synopsis", x => synopsis = x, this);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "completedMessage", x => completedMessage = x, this);

                if (configNode.HasValue("motivation)"))
                {
                    string motivation;
                    valid &= ConfigNodeUtil.ParseValue <string>(configNode, "motivation", x => motivation = x, this, "");
                    LoggingUtil.LogWarning(this, "The 'motivation' attribute is no longer supported as of Contract Configurator 1.23.0");
                }

                // Load optional attributes
                valid &= ConfigNodeUtil.ParseValue <Agent>(configNode, "agent", x => agent = x, this, group != null ? group.agent : null);
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "minExpiry", x => minExpiry = x, this, 5.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "maxExpiry", x => maxExpiry = x, this, 100.0f, x => Validation.GE(x, minExpiry));
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "deadline", x => deadline = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue <bool>(configNode, "cancellable", x => cancellable = x, this, true);
                valid &= ConfigNodeUtil.ParseValue <bool>(configNode, "declinable", x => declinable = x, this, true);
                valid &= ConfigNodeUtil.ParseValue <bool>(configNode, "autoAccept", x => autoAccept = x, this, false);
                valid &= ConfigNodeUtil.ParseValue <List <Contract.ContractPrestige> >(configNode, "prestige", x => prestige = x, this, new List <Contract.ContractPrestige>());
                valid &= ConfigNodeUtil.ParseValue <CelestialBody>(configNode, "targetBody", x => targetBody = x, this, (CelestialBody)null);

                valid &= ConfigNodeUtil.ParseValue <int>(configNode, "maxCompletions", x => maxCompletions = x, this, 0, x => Validation.GE(x, 0));
                valid &= ConfigNodeUtil.ParseValue <int>(configNode, "maxSimultaneous", x => maxSimultaneous = x, this, (maxCompletions == 0 ? 4 : 0), x => Validation.GE(x, 0));

                // Load rewards
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "rewardFunds", x => rewardFunds = x, this, 0.0f);
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "rewardReputation", x => rewardReputation = x, this, 0.0f);
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "rewardScience", x => rewardScience = x, this, 0.0f);
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "failureFunds", x => failureFunds = x, this, 0.0f);
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "failureReputation", x => failureReputation = x, this, 0.0f);
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "advanceFunds", x => advanceFunds = x, this, 0.0f);

                // Load other values
                if (configNode.HasValue("weight"))
                {
                    double weight;
                    valid &= ConfigNodeUtil.ParseValue <double>(configNode, "weight", x => weight = x, this);
                    LoggingUtil.LogWarning(this, ErrorPrefix() + ": The weight attribute is deprecated as of Contract Configurator 1.15.0.  Contracts are no longer generated using a weighted system.");
                }

                // Merge in data from the parent contract group
                for (ContractGroup currentGroup = group; currentGroup != null; currentGroup = currentGroup.parent)
                {
                    // Merge dataValues - this is a flag saying what values need to be unique at the contract level
                    foreach (KeyValuePair <string, DataValueInfo> pair in currentGroup.dataValues)
                    {
                        dataValues[currentGroup.name + ":" + pair.Key] = pair.Value;
                    }

                    // Merge uniquenessChecks
                    foreach (KeyValuePair <string, DataNode.UniquenessCheck> pair in currentGroup.uniquenessChecks)
                    {
                        uniquenessChecks[currentGroup.name + ":" + pair.Key] = pair.Value;
                    }
                }

                // Load DATA nodes
                valid &= dataNode.ParseDataNodes(configNode, this, dataValues, uniquenessChecks);

                log = LoggingUtil.capturedLog;
                LoggingUtil.CaptureLog = false;

                // Load parameters
                foreach (ConfigNode contractParameter in ConfigNodeUtil.GetChildNodes(configNode, "PARAMETER"))
                {
                    ParameterFactory paramFactory = null;
                    valid &= ParameterFactory.GenerateParameterFactory(contractParameter, this, out paramFactory);
                    if (paramFactory != null)
                    {
                        paramFactories.Add(paramFactory);
                        if (paramFactory.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Load behaviours
                foreach (ConfigNode requirementNode in ConfigNodeUtil.GetChildNodes(configNode, "BEHAVIOUR"))
                {
                    BehaviourFactory behaviourFactory = null;
                    valid &= BehaviourFactory.GenerateBehaviourFactory(requirementNode, this, out behaviourFactory);
                    if (behaviourFactory != null)
                    {
                        behaviourFactories.Add(behaviourFactory);
                        if (behaviourFactory.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Load requirements
                foreach (ConfigNode requirementNode in ConfigNodeUtil.GetChildNodes(configNode, "REQUIREMENT"))
                {
                    ContractRequirement requirement = null;
                    valid &= ContractRequirement.GenerateRequirement(requirementNode, this, out requirement);
                    if (requirement != null)
                    {
                        requirements.Add(requirement);
                        if (requirement.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Logging on
                LoggingUtil.CaptureLog = true;

                // Check we have at least one valid parameter
                if (paramFactories.Count() == 0)
                {
                    LoggingUtil.LogError(this, ErrorPrefix() + ": Need at least one parameter for a contract!");
                    valid = false;
                }

                ConfigNodeUtil.SetCurrentDataNode(dataNode);

                //
                // Process the DATA_EXPAND nodes - this could cause a restart to the load process
                //
                ConfigNode dataExpandNode = configNode.GetNodes("DATA_EXPAND").FirstOrDefault();
                if (dataExpandNode != null)
                {
                    Type type = null;
                    valid &= ConfigNodeUtil.ParseValue <Type>(dataExpandNode, "type", x => type = x, this);

                    if (type != null)
                    {
                        foreach (ConfigNode.Value pair in dataExpandNode.values)
                        {
                            string key = pair.name;
                            if (key != "type")
                            {
                                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 ParseDataExpandString method generic value
                                MethodInfo method = methodParseExpand.MakeGenericMethod(new Type[] { type });

                                // Invoke the ParseDataExpandString method
                                List <string> values = (List <string>)method.Invoke(this, new object[] { dataExpandNode, key });

                                // Stop at this point if we're invalid
                                if (values == null || !valid)
                                {
                                    if (values == null)
                                    {
                                        LoggingUtil.LogWarning(this, ErrorPrefix() + ": Received an empty list of values when trying to do a DATA_EXPAND");
                                    }
                                    valid = false;
                                    break;
                                }

                                // Expand
                                configNode.RemoveNode(dataExpandNode);
                                foreach (string val in values)
                                {
                                    // Set up for expansion
                                    ConfigNode copy    = configNode.CreateCopy();
                                    string     newName = name + "." + val;
                                    copy.SetValue("name", newName);

                                    // Set up the data node in the copy
                                    ConfigNode dataNode = new ConfigNode("DATA");
                                    copy.AddNode(dataNode);
                                    dataNode.AddValue("type", dataExpandNode.GetValue("type"));
                                    dataNode.AddValue(key, val);

                                    ContractType contractTypeCopy = new ContractType(newName);
                                    contractTypeCopy.Load(copy);
                                }

                                // Remove the original
                                contractTypes.Remove(name);

                                // Don't do any more loading for this one
                                LoggingUtil.LogInfo(this, "Successfully expanded CONTRACT_TYPE '" + name + "'");
                                return(valid);
                            }
                        }
                    }
                }

                //
                // Do the deferred loads
                //
                valid &= ConfigNodeUtil.ExecuteDeferredLoads();

                //
                // Do generic fields that need to happen after deferred loads
                //
                ConfigNodeUtil.SetCurrentDataNode(dataNode);

                // Generic title
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "genericTitle", x => genericTitle = x, this, title);
                if (!configNode.HasValue("genericTitle") && !dataNode.IsDeterministic("title"))
                {
                    LoggingUtil.Log(minVersion >= ContractConfigurator.ENHANCED_UI_VERSION ? LoggingUtil.LogLevel.ERROR : LoggingUtil.LogLevel.WARNING, this,
                                    ErrorPrefix() + ": The field 'genericTitle' is required when the title is not determistic (ie. when expressions are used).");

                    // Error on newer versions of contract packs
                    if (minVersion >= ContractConfigurator.ENHANCED_UI_VERSION)
                    {
                        valid = false;
                    }
                }
                else if (!dataNode.IsDeterministic("genericTitle"))
                {
                    valid = false;
                    LoggingUtil.LogError(this, ErrorPrefix() + ": The field 'genericTitle' must be deterministic.");
                }

                // Generic description
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "genericDescription", x => genericDescription = x, this, description);
                if (!configNode.HasValue("genericDescription") && !dataNode.IsDeterministic("description"))
                {
                    LoggingUtil.Log(minVersion >= ContractConfigurator.ENHANCED_UI_VERSION ? LoggingUtil.LogLevel.ERROR : LoggingUtil.LogLevel.WARNING, this,
                                    ErrorPrefix() + ": The field 'genericDescription' is required when the description is not determistic (ie. when expressions are used).");

                    // Error on newer versions of contract packs
                    if (minVersion >= ContractConfigurator.ENHANCED_UI_VERSION)
                    {
                        valid = false;
                    }
                }
                else if (!dataNode.IsDeterministic("genericDescription"))
                {
                    valid = false;
                    LoggingUtil.LogError(this, ErrorPrefix() + ": The field 'genericDescription' must be deterministic.");
                }

                // Sorting key
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "sortKey", x => sortKey = x, this, genericTitle);

                // Check for unexpected values - always do this last
                valid &= ConfigNodeUtil.ValidateUnexpectedValues(configNode, this);

                if (valid)
                {
                    LoggingUtil.LogInfo(this, "Successfully loaded CONTRACT_TYPE '" + name + "'");
                }
                else
                {
                    LoggingUtil.LogWarning(this, "Errors encountered while trying to load CONTRACT_TYPE '" + name + "'");
                }
                config  = configNode.ToString();
                hash    = config.GetHashCode();
                enabled = valid;
                log    += LoggingUtil.capturedLog;

                if (LoggingUtil.logLevel >= LoggingUtil.LogLevel.DEBUG)
                {
                    // Get the contract configurator log file
                    string[] dirComponents  = new string[] { KSPUtil.ApplicationRootPath, "GameData", "ContractConfigurator", "log", (group == null ? "!NO_GROUP" : group.Root.name) };
                    string[] pathComponents = dirComponents.Union(new string[] { name + ".log" }).ToArray();
                    string   dir            = string.Join(Path.DirectorySeparatorChar.ToString(), dirComponents);
                    string   path           = string.Join(Path.DirectorySeparatorChar.ToString(), pathComponents);

                    // Delete the file if it exists
                    if (File.Exists(path))
                    {
                        try
                        {
                            File.Delete(path);
                        }
                        catch (Exception e)
                        {
                            LoggingUtil.LogException(new Exception("Exception while attempting to delete the file: " + path, e));
                        }
                    }

                    // Create the directory if it doesn't exist
                    Directory.CreateDirectory(dir);

                    // Now write the config and the cleaned up log to it
                    try
                    {
                        using (StreamWriter sw = File.AppendText(path))
                        {
                            sw.Write("Debug information for CONTRACT_TYPE '" + name + "':\n");
                            sw.Write("\nConfiguration:\n");
                            sw.Write(config);
                            sw.Write("\nData Nodes:\n");
                            sw.Write(DataNodeDebug(dataNode));
                            sw.Write("\nOutput log:\n");
                            sw.Write(log);
                        }
                    }
                    catch
                    {
                        LoggingUtil.LogError(this, "Exception while attempting to write to the file: " + path);
                    }
                }

                return(valid);
            }
            catch (Exception e)
            {
                enabled = false;
                throw new Exception("Error loading CONTRACT_TYPE '" + name + "'", e);
            }
            finally
            {
                LoggingUtil.CaptureLog = false;
                LoggingUtil.logLevel   = origLogLevel;
                loaded = true;
            }
        }
        private void ContractGroupLine(ContractGroup contractGroup, int indent = 0)
        {
            string identifier = contractGroup == null ? "" : contractGroup.name;
            if (!contractGroupDetails.ContainsKey(identifier))
            {
                contractGroupDetails[identifier] = new ContractGroupDetails(contractGroup);
            }
            ContractGroupDetails details = contractGroupDetails[identifier];

            GUILayout.BeginHorizontal();

            GUILayout.Label("", contractRegularText, GUILayout.ExpandWidth(false), GUILayout.Width((indent+1) * 16));

            string groupName = contractGroup == null ? "No Group" : contractGroup.displayName;
            GUILayout.Label(groupName, details.enabled ? contractRegularText : contractDisabledText, GUILayout.ExpandWidth(true));
            if (contractGroup != null && contractGroup.parent == null)
            {
                bool enabled = GUILayout.Toggle(details.enabled,
                    new GUIContent("", "Click to " + (details.enabled ? "disable " : "enable ") + contractGroup.displayName + " contracts."),
                    contractToggleStyle, GUILayout.ExpandWidth(false));

                if (enabled != details.enabled)
                {
                    details.enabled = enabled;
                    if (enabled)
                    {
                        foreach (KeyValuePair<Type, StockContractDetails> pair in stockContractDetails.
                            Where(p => ContractDisabler.DisablingGroups(p.Key).Contains(contractGroup)))
                        {
                            pair.Value.enabled = false;
                            ContractDisabler.SetContractState(pair.Key, false);
                        }
                    }
                    else
                    {
                        foreach (KeyValuePair<Type, StockContractDetails> pair in stockContractDetails.
                            Where(p => ContractDisabler.DisablingGroups(p.Key).Contains(contractGroup) &&
                                ContractDisabler.DisablingGroups(p.Key).All(g => !IsEnabled(g))))
                        {
                            pair.Value.enabled = true;
                            ContractDisabler.SetContractState(pair.Key, true);
                        }
                    }
                }
            }
            GUILayout.EndHorizontal();
        }
        public ContractType(string name)
        {
            this.name = name;
            contractTypes.Add(name, this);

            // Member defaults
            group = null;
            agent = null;
            minExpiry = 0;
            maxExpiry = 0;
            deadline = 0;
            cancellable = true;
            declinable = true;
            autoAccept = false;
            prestige = new List<Contract.ContractPrestige>();
            maxCompletions = 0;
            maxSimultaneous = 0;
            rewardScience = 0.0f;
            rewardReputation = 0.0f;
            rewardFunds = 0.0f;
            failureReputation = 0.0f;
            failureFunds = 0.0f;
            advanceFunds = 0.0f;
            weight = 1.0;
            enabled = true;
        }
 public ContractGroupDetails(ContractGroup group)
 {
     this.group = group;
 }
        protected bool CheckContractGroup(ConfiguredContract contract, ContractGroup group)
        {
            if (group != null)
            {
                // Check the group is enabled
                if (!ContractConfiguratorSettings.IsEnabled(group))
                {
                    throw new ContractRequirementException("Contract group " + group.name + " is not enabled.");
                }

                IEnumerable<ConfiguredContract> contractList = ContractSystem.Instance.GetCurrentContracts<ConfiguredContract>().
                    Where(c => c.contractType != null);

                // Special case for pre-loader contracts
                if (contract.ContractState == Contract.State.Withdrawn)
                {
                    contractList = contractList.Union(ContractPreLoader.Instance.PendingContracts(contract.Prestige));
                    contractList = contractList.Where(c => c != contract);
                }

                // Check the group active limit
                int activeContracts = contractList.Count(c => c.contractType != null && group.BelongsToGroup(c.contractType));
                if (contract.ContractState == Contract.State.Offered || contract.ContractState == Contract.State.Active)
                {
                    activeContracts--;
                }

                if (group.maxSimultaneous != 0 && activeContracts >= group.maxSimultaneous)
                {
                    throw new ContractRequirementException("Too many active contracts in group (" + group.name + ").");
                }

                // Check the group completed limit
                if (group.maxCompletions != 0)
                {
                    int finishedContracts = ContractSystem.Instance.GetCompletedContracts<ConfiguredContract>().Count(c => c.contractType != null && group.BelongsToGroup(c.contractType));
                    if (finishedContracts + activeContracts >= maxCompletions)
                    {
                        throw new ContractRequirementException("Too many completed contracts in group (" + group.name + ").");
                    }
                }

                return CheckContractGroup(contract, group.parent);
            }

            return true;
        }
        /// <summary>
        /// Loads the contract type details from the given config node.
        /// </summary>
        /// <param name="configNode">The config node to load from.</param>
        /// <returns>Whether the load was successful.</returns>
        public bool Load(ConfigNode configNode)
        {
            LoggingUtil.LogLevel origLogLevel = LoggingUtil.logLevel;

            try
            {
                // Logging on
                LoggingUtil.CaptureLog = true;

                dataNode = new DataNode(configNode.GetValue("name"), this);

                ConfigNodeUtil.SetCurrentDataNode(dataNode);
                bool valid = true;

                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "name", x => name = x, this);

                // Try to turn on trace mode
                valid &= ConfigNodeUtil.ParseValue<bool>(configNode, "trace", x => trace = x, this, false);
                if (trace)
                {
                    LoggingUtil.logLevel = LoggingUtil.LogLevel.VERBOSE;
                    LoggingUtil.LogWarning(this, "Tracing enabled for contract type " + name);
                }

                // Load contract text details
                valid &= ConfigNodeUtil.ParseValue<ContractGroup>(configNode, "group", x => group = x, this, (ContractGroup)null);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "title", x => title = x, this);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "tag", x => tag = x, this, "");
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "description", x => description = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "topic", x => topic = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "subject", x => subject = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "motivation", x => motivation = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "notes", x => notes = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "synopsis", x => synopsis = x, this);
                valid &= ConfigNodeUtil.ParseValue<string>(configNode, "completedMessage", x => completedMessage = x, this);

                // Load optional attributes
                valid &= ConfigNodeUtil.ParseValue<Agent>(configNode, "agent", x => agent = x, this, (Agent)null);
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "minExpiry", x => minExpiry = x, this, 1.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "maxExpiry", x => maxExpiry = x, this, 7.0f, x => Validation.GE(x, minExpiry));
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "deadline", x => deadline = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue<bool>(configNode, "cancellable", x => cancellable = x, this, true);
                valid &= ConfigNodeUtil.ParseValue<bool>(configNode, "declinable", x => declinable = x, this, true);
                valid &= ConfigNodeUtil.ParseValue<bool>(configNode, "autoAccept", x => autoAccept = x, this, false);
                valid &= ConfigNodeUtil.ParseValue<List<Contract.ContractPrestige>>(configNode, "prestige", x => prestige = x, this, new List<Contract.ContractPrestige>());
                valid &= ConfigNodeUtil.ParseValue<CelestialBody>(configNode, "targetBody", x => targetBody = x, this, (CelestialBody)null);

                valid &= ConfigNodeUtil.ParseValue<int>(configNode, "maxCompletions", x => maxCompletions = x, this, 0, x => Validation.GE(x, 0));
                valid &= ConfigNodeUtil.ParseValue<int>(configNode, "maxSimultaneous", x => maxSimultaneous = x, this, 0, x => Validation.GE(x, 0));

                // Load rewards
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "rewardFunds", x => rewardFunds = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "rewardReputation", x => rewardReputation = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "rewardScience", x => rewardScience = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "failureFunds", x => failureFunds = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "failureReputation", x => failureReputation = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue<float>(configNode, "advanceFunds", x => advanceFunds = x, this, 0.0f, x => Validation.GE(x, 0.0f));

                // Load other values
                valid &= ConfigNodeUtil.ParseValue<double>(configNode, "weight", x => weight = x, this, 1.0, x => Validation.GE(x, 0.0f));

                // Load DATA nodes
                valid &= DataNode.ParseDataNodes(configNode, this, dataValues, uniqueValues);

                // Check for unexpected values - always do this last
                valid &= ConfigNodeUtil.ValidateUnexpectedValues(configNode, this);

                log = LoggingUtil.capturedLog;
                LoggingUtil.CaptureLog = false;

                // Load parameters
                foreach (ConfigNode contractParameter in ConfigNodeUtil.GetChildNodes(configNode, "PARAMETER"))
                {
                    ParameterFactory paramFactory = null;
                    valid &= ParameterFactory.GenerateParameterFactory(contractParameter, this, out paramFactory);
                    if (paramFactory != null)
                    {
                        paramFactories.Add(paramFactory);
                        if (paramFactory.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Load behaviours
                foreach (ConfigNode requirementNode in ConfigNodeUtil.GetChildNodes(configNode, "BEHAVIOUR"))
                {
                    BehaviourFactory behaviourFactory = null;
                    valid &= BehaviourFactory.GenerateBehaviourFactory(requirementNode, this, out behaviourFactory);
                    if (behaviourFactory != null)
                    {
                        behaviourFactories.Add(behaviourFactory);
                        if (behaviourFactory.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Load requirements
                foreach (ConfigNode requirementNode in ConfigNodeUtil.GetChildNodes(configNode, "REQUIREMENT"))
                {
                    ContractRequirement requirement = null;
                    valid &= ContractRequirement.GenerateRequirement(requirementNode, this, out requirement);
                    if (requirement != null)
                    {
                        requirements.Add(requirement);
                        if (requirement.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Logging on
                LoggingUtil.CaptureLog = true;

                // Check we have at least one valid parameter
                if (paramFactories.Count() == 0)
                {
                    LoggingUtil.LogError(this.GetType(), ErrorPrefix() + ": Need at least one parameter for a contract!");
                    valid = false;
                }

                // Do the deferred loads
                valid &= ConfigNodeUtil.ExecuteDeferredLoads();

                config = configNode.ToString();
                hash = config.GetHashCode();
                enabled = valid;
                log += LoggingUtil.capturedLog;
                LoggingUtil.CaptureLog = false;

                return valid;
            }
            catch
            {
                enabled = false;
                throw;
            }
            finally
            {
                LoggingUtil.logLevel = origLogLevel;
                loaded = true;
            }
        }
Example #31
0
        private static void GroupGui(ContractGroup contractGroup, int indent)
        {
            if (contractGroup != null)
            {
                GUILayout.BeginHorizontal();

                if (indent != 0)
                {
                    GUILayout.Label("", GUILayout.ExpandWidth(false), GUILayout.Width(indent * 16));
                }

                if (GUILayout.Button(contractGroup.expandInDebug ? "-" : "+", GUILayout.Width(20), GUILayout.Height(20)))
                {
                    contractGroup.expandInDebug = !contractGroup.expandInDebug;
                }

                GUIStyle style = greenLabel;
                if (!contractGroup.enabled)
                {
                    style = redLabel;
                }
                else
                {
                    if (contractGroup.hasWarnings)
                    {
                        style = yellowLabel;
                    }

                    foreach (ContractType contractType in guiContracts.Where(ct => contractGroup == null ? ct.group == null : contractGroup.BelongsToGroup(ct)))
                    {
                        if (!contractType.enabled)
                        {
                            style = redLabel;
                            break;
                        }
                        else if (contractType.hasWarnings)
                        {
                            style = yellowLabel;
                        }
                    }
                }

                GUILayout.Label(new GUIContent(contractGroup.ToString(), DebugInfo(contractGroup)), style);
                GUILayout.EndHorizontal();
            }

            if (contractGroup == null || contractGroup.expandInDebug)
            {
                // Child groups
                if (contractGroup != null)
                {
                    foreach (ContractGroup childGroup in ContractGroup.AllGroups.Where(g => g != null && g.parent != null && g.parent.name == contractGroup.name).OrderBy(cg => cg.name))
                    {
                        GroupGui(childGroup, indent + 1);
                    }
                }

                // Child contract types
                foreach (ContractType contractType in guiContracts.Where(ct => ct.group == contractGroup).OrderBy(ct => ct.name))
                {
                    GUILayout.BeginHorizontal();

                    if (contractGroup != null)
                    {
                        GUILayout.Label("", GUILayout.ExpandWidth(false), GUILayout.Width((indent + 1) * 16));
                    }

                    if (GUILayout.Button(contractType.expandInDebug ? "-" : "+", GUILayout.Width(20), GUILayout.Height(20)))
                    {
                        contractType.expandInDebug = !contractType.expandInDebug;
                    }
                    GUILayout.Label(new GUIContent(contractType.ToString(), DebugInfo(contractType)),
                                    contractType.enabled ? contractType.hasWarnings ? yellowLabel : GUI.skin.label : redLabel);
                    GUILayout.EndHorizontal();

                    if (contractType.expandInDebug)
                    {
                        // Output children
                        ParamGui(contractType, contractType.ParamFactories, indent + (contractGroup == null ? 1 : 2));
                        RequirementGui(contractType, contractType.Requirements, indent + (contractGroup == null ? 1 : 2));
                        BehaviourGui(contractType, contractType.BehaviourFactories, indent + (contractGroup == null ? 1 : 2));

                        GUILayout.Space(8);
                    }
                }
            }
        }
        protected bool CheckContractGroup(ConfiguredContract contract, ContractGroup group)
        {
            if (group != null)
            {
                // Check the group is enabled
                if (!ContractConfiguratorSettings.IsEnabled(group))
                {
                    throw new ContractRequirementException("Contract group " + group.name + " is not enabled.");
                }

                // Check the group active limit
                int activeContracts = ContractSystem.Instance.GetCurrentContracts<ConfiguredContract>().Count(c => c.contractType != null && group.BelongsToGroup(c.contractType));
                if (contract.ContractState == Contract.State.Offered || contract.ContractState == Contract.State.Active)
                {
                    activeContracts--;
                }

                if (group.maxSimultaneous != 0 && activeContracts >= group.maxSimultaneous)
                {
                    throw new ContractRequirementException("Too many active contracts in group (" + group.name + ").");
                }

                // Check the group completed limit
                if (group.maxCompletions != 0)
                {
                    int finishedContracts = ContractSystem.Instance.GetCompletedContracts<ConfiguredContract>().Count(c => c.contractType != null && group.BelongsToGroup(c.contractType));
                    if (finishedContracts + activeContracts >= maxCompletions)
                    {
                        throw new ContractRequirementException("Too many completed contracts in group (" + group.name + ").");
                    }
                }

                return CheckContractGroup(contract, group.parent);
            }

            return true;
        }
Example #33
0
        private IEnumerable <ConfiguredContract> GenerateContract(ContractType contractType)
        {
            // Set the desired prestige
            int t1, t2, t3;

            ContractSystem.GetContractCounts(Reputation.CurrentRep, 1000, out t1, out t2, out t3);
            if (contractType.prestige.Any())
            {
                if (!contractType.prestige.Contains(Contract.ContractPrestige.Trivial))
                {
                    t1 = 0;
                }
                if (!contractType.prestige.Contains(Contract.ContractPrestige.Significant))
                {
                    t2 = 0;
                }
                if (!contractType.prestige.Contains(Contract.ContractPrestige.Exceptional))
                {
                    t3 = 0;
                }
            }
            int selection = rand.Next(0, t1 + t2 + t3);

            Contract.ContractPrestige prestige = selection < t1 ? Contract.ContractPrestige.Trivial : selection < (t1 + t2) ? Contract.ContractPrestige.Significant : Contract.ContractPrestige.Exceptional;

            // Generate the template
            ConfiguredContract templateContract = Contract.Generate(typeof(ConfiguredContract), prestige, rand.Next(), Contract.State.Withdrawn) as ConfiguredContract;

            // First, check the basic requirements
            if (!contractType.MeetBasicRequirements(templateContract))
            {
                LoggingUtil.LogVerbose(this, "{0} was not generated: basic requirements not met.", contractType.name);
                if (++contractType.failedGenerationAttempts >= contractType.maxConsecutiveGenerationFailures)
                {
                    contractType.lastGenerationFailure = Time.realtimeSinceStartup;
                }

                yield return(null);

                yield break;
            }

            // Try to refresh non-deterministic values before we check extended requirements
            OnInitializeValues.Fire();
            LoggingUtil.LogLevel origLogLevel = LoggingUtil.logLevel;
            LoggingUtil.LogLevel newLogLevel  = contractType.trace ? LoggingUtil.LogLevel.VERBOSE : LoggingUtil.logLevel;
            try
            {
                // Set up for loop
                LoggingUtil.logLevel = newLogLevel;
                ConfiguredContract.currentContract = templateContract;

                // Set up the iterator to refresh non-deterministic values
                IEnumerable <string> iter = ConfigNodeUtil.UpdateNonDeterministicValuesIterator(contractType.dataNode);
                for (ContractGroup g = contractType.group; g != null; g = g.parent)
                {
                    iter = ConfigNodeUtil.UpdateNonDeterministicValuesIterator(g.dataNode).Concat(iter);
                }

                // Update the actual values
                LoggingUtil.LogVerbose(this, "Refresh non-deterministic values for CONTRACT_TYPE = {0}", contractType.name);
                foreach (string val in iter)
                {
                    lastKey = contractType.name + "[" + val + "]";

                    // Clear temp stuff
                    LoggingUtil.logLevel = origLogLevel;
                    ConfiguredContract.currentContract = null;

                    if (val == null)
                    {
                        LoggingUtil.LogVerbose(this, "{0} was not generated: non-deterministic expression failure.", contractType.name);
                        if (++contractType.failedGenerationAttempts >= contractType.maxConsecutiveGenerationFailures)
                        {
                            contractType.lastGenerationFailure = Time.realtimeSinceStartup;
                        }

                        OnInitializeFail.Fire();
                        yield return(null);

                        yield break;
                    }
                    else
                    {
                        // Quick pause
                        yield return(null);
                    }

                    // Re set up
                    LoggingUtil.logLevel = newLogLevel;
                    ConfiguredContract.currentContract = templateContract;
                }
            }
            finally
            {
                LoggingUtil.logLevel = origLogLevel;
                ConfiguredContract.currentContract = null;
            }

            // Store unique data
            foreach (string key in contractType.uniquenessChecks.Keys)
            {
                if (contractType.dataNode.GetType(key) == typeof(Vessel))
                {
                    Vessel v = contractType.dataNode[key] as Vessel;
                    templateContract.uniqueData[key] = v != null ? (object)v.id : null;
                }
                else
                {
                    templateContract.uniqueData[key] = contractType.dataNode[key];
                }
            }
            templateContract.targetBody = contractType.targetBody;

            // Check the requirements for our selection
            if (contractType.MeetExtendedRequirements(templateContract, contractType) && templateContract.Initialize(contractType))
            {
                templateContract.ContractState = Contract.State.Offered;
                yield return(templateContract);
            }
            // Failure, add a pause in before finishing
            else
            {
                LoggingUtil.LogVerbose(this, "{0} was not generated: requirement not met.", contractType.name);
                if (++contractType.failedGenerationAttempts >= contractType.maxConsecutiveGenerationFailures)
                {
                    contractType.lastGenerationFailure = Time.realtimeSinceStartup;
                }

                OnInitializeFail.Fire();
                yield return(null);
            }
        }
Example #34
0
 public ContractGroupDetails(ContractGroup group)
 {
     this.group = group;
 }