コード例 #1
0
        /// <summary>
        /// Generates all the ContractParameter objects required for the array of ConfigNodes, and
        /// adds them to the host object.
        /// </summary>
        /// <param name="contract">Contract to generate for</param>
        /// <param name="contractParamHost">The object to use as a parent for ContractParameters</param>
        /// <param name="paramFactories">The ParameterFactory objects to use to generate parameters.</param>
        /// <returns>Whether the generation was successful.</returns>
        public static bool GenerateParameters(ConfiguredContract contract, IContractParameterHost contractParamHost, List <ParameterFactory> paramFactories)
        {
            foreach (ParameterFactory paramFactory in paramFactories)
            {
                if (paramFactory.enabled)
                {
                    // Set up the iterator
                    int count   = 1;
                    int current = 0;
                    if (paramFactory.iteratorType != null)
                    {
                        count = (int)paramFactory.dataNode["iteratorCount"];
                    }

                    // Loop through the iterator, or do a single parameter for non-iterated parameters
                    while (current++ < count)
                    {
                        // Refresh the deterministic values
                        int oldValue = DataNode.IteratorCurrentIndex;
                        if (paramFactory.iteratorType != null)
                        {
                            DataNode.IteratorCurrentIndex = current - 1;
                            ConfigNodeUtil.UpdateNonDeterministicValues(paramFactory.dataNode, paramFactory.dataNode);
                        }

                        ContractParameter parameter = paramFactory.Generate(contract, contractParamHost);

                        // Get the child parameters
                        if (parameter != null)
                        {
                            if (!GenerateParameters(contract, parameter, paramFactory.childNodes))
                            {
                                return(false);
                            }
                        }

                        ContractConfiguratorParameter ccParam = parameter as ContractConfiguratorParameter;
                        if (ccParam != null && ccParam.hideChildren)
                        {
                            foreach (ContractParameter child in ccParam.GetChildren())
                            {
                                ContractConfiguratorParameter ccChild = child as ContractConfiguratorParameter;
                                if (ccChild != null)
                                {
                                    ccChild.Hide();
                                }
                            }
                        }

                        // Restore the old value for the iterator list (for recursive iterations)
                        DataNode.IteratorCurrentIndex = oldValue;
                    }
                }
            }

            return(true);
        }
コード例 #2
0
        private bool SelectContractType()
        {
            if (!lastSpecificGenerationFailure.ContainsKey(prestige))
            {
                lastSpecificGenerationFailure[prestige] = 0;
            }

            LoggingUtil.LogVerbose(this, "Generating a contract for prestige = " + prestige);

            // Loop through all the contract groups
            IEnumerable <ContractGroup> groups = ContractGroup.AllGroups;

            foreach (ContractGroup group in groups.Skip(nextGroup).Concat(groups.Take(nextGroup)))
            {
                LoggingUtil.LogVerbose(this, "Looking at group " + group);
                nextGroup = (nextGroup + 1) % groups.Count();

                // 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))
                {
                    LoggingUtil.LogVerbose(this, "Checking ContractType = " + ct.name);
                    // KSP tries to generate new contracts *incessantly*, to the point where this becomes
                    // a real performance problem.  So if we run into a situation where we did not
                    // generate a contract and we are asked AGAIN after a very short time, then do
                    // some logic to prevent re-checking uselessly.

                    // If there was any generation failure within the last 100 frames, only look at
                    // contracts specific to that prestige level
                    if (lastGenerationFailure + 100 > Time.frameCount)
                    {
                        // If there was a generation failure for this specific prestige level in
                        // the last 100 frames, then just skip the checks entirely
                        if (lastSpecificGenerationFailure[prestige] + 100 > Time.frameCount)
                        {
                            return(false);
                        }
                    }

                    // 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
                System.Random generator = new System.Random(this.MissionSeed);
                while (validContractTypes.Count > 0)
                {
                    ContractType selectedContractType = null;
                    // Pick one of the contract types based on their weight
                    double value = generator.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;
                    }

                    // Try to refresh non-deterministic values before we check requirements
                    currentContract = this;
                    LoggingUtil.LogVerbose(this, "Refresh non-deterministic values for CONTRACT_TYPE = " + selectedContractType.name);
                    if (!ConfigNodeUtil.UpdateNonDeterministicValues(selectedContractType.dataNode))
                    {
                        LoggingUtil.LogVerbose(this, selectedContractType.name + " was not generated: non-deterministic expression failure.");
                        validContractTypes.Remove(selectedContractType);
                        totalWeight -= selectedContractType.weight;
                    }
                    currentContract = null;

                    // Check the requirements for our selection
                    if (selectedContractType.MeetRequirements(this))
                    {
                        contractType = selectedContractType;
                        subType      = contractType.name;
                        return(true);
                    }
                    // Remove the selection, and try again
                    else
                    {
                        LoggingUtil.LogVerbose(this, selectedContractType.name + " was not generated: requirement not met.");
                        validContractTypes.Remove(selectedContractType);
                        totalWeight -= selectedContractType.weight;
                    }
                }
            }

            // Set our failure markers
            lastGenerationFailure = Time.frameCount;
            lastSpecificGenerationFailure[prestige] = Time.frameCount;

            return(false);
        }