예제 #1
0
        /*
         * Returns true if the contract can be offered.
         */
        public bool MeetRequirements(ConfiguredContract contract)
        {
            // Check prestige
            if (prestige != null && contract.Prestige != prestige)
            {
                return(false);
            }

            // Get the count of active contracts - excluding ours
            int activeContracts = ContractSystem.Instance.GetCurrentContracts <ConfiguredContract>().Count(c => c.contractType == this);

            if (contract.ContractState == Contract.State.Offered || contract.ContractState == Contract.State.Active)
            {
                activeContracts--;
            }

            // Check if we're breaching the active limit
            if (maxSimultaneous != 0 && activeContracts >= maxSimultaneous)
            {
                return(false);
            }

            // Check if we're breaching the completed limit
            if (maxCompletions != 0)
            {
                int finishedContracts = ContractSystem.Instance.GetCompletedContracts <ConfiguredContract>().Count(c => c.contractType == this);
                if (finishedContracts + activeContracts >= maxCompletions)
                {
                    return(false);
                }
            }

            // Check the captured requirements
            return(ContractRequirement.RequirementsMet(contract, this, requirements));
        }
        /// <summary>
        /// Method for generating ContractParameter objects.  This will call the Generate() method
        /// on the sub-class, load all common parameters and load child parameters.
        /// </summary>
        /// <param name="contract">Contract to generate for</param>
        /// <param name="contractParamHost">Parent object for the ContractParameter</param>
        /// <returns>Generated ContractParameter</returns>
        public virtual ContractParameter Generate(ConfiguredContract contract, IContractParameterHost contractParamHost)
        {
            // First check any requirements
            if (!ContractRequirement.RequirementsMet(contract, contract.contractType, requirements))
            {
                LoggingUtil.LogVerbose(typeof(ParameterFactory), "Returning null for " + contract.contractType.name + "." + name + ": requirements not met.");
                return(null);
            }

            // Generate a parameter using the sub-class logic
            ContractParameter parameter = Generate(contract);

            if (parameter == null)
            {
                LoggingUtil.LogWarning(this, GetType().FullName + ".Generate() returned a null ContractParameter!");
                return(null);
            }

            // Add ContractParameter to the host
            contractParamHost.AddParameter(parameter);

            // Set the funds/science/reputation parameters
            parameter.SetFunds(rewardFunds, failureFunds, targetBody);
            parameter.SetReputation(rewardReputation, failureReputation, targetBody);
            parameter.SetScience(rewardScience, targetBody);

            // Set other flags
            parameter.Optional = optional;
            if (disableOnStateChange != null)
            {
                parameter.DisableOnStateChange = (bool)disableOnStateChange;
            }
            parameter.ID = name;

            // Special stuff for contract configurator parameters
            ContractConfiguratorParameter ccParam = parameter as ContractConfiguratorParameter;

            if (ccParam != null)
            {
                ccParam.completeInSequence = completeInSequence;
                ccParam.notes            = notes;
                ccParam.completedMessage = completedMessage;
                ccParam.hidden           = hidden;
                ccParam.hideChildren     = hideChildren;
            }

            return(parameter);
        }
예제 #3
0
        /// <summary>
        /// Checks if the "extended" requirements that change due to expressions.
        /// </summary>
        /// <param name="contract">The contract</param>
        /// <returns>Whether the contract can be offered.</returns>
        public bool MeetExtendedRequirements(ConfiguredContract contract, ContractType contractType)
        {
            LoggingUtil.LogLevel origLogLevel = LoggingUtil.logLevel;
            try
            {
                // Turn tracing on
                if (trace)
                {
                    LoggingUtil.logLevel = LoggingUtil.LogLevel.VERBOSE;
                    LoggingUtil.LogWarning(this, "Tracing enabled for contract type " + name);
                }

                // Hash check
                if (contract.ContractState == Contract.State.Offered && contract.hash != hash)
                {
                    throw new ContractRequirementException("Contract definition changed.");
                }

                // Check prestige
                if (prestige.Count > 0 && !prestige.Contains(contract.Prestige))
                {
                    throw new ContractRequirementException("Wrong prestige level.");
                }

                // Do a Research Bodies check, if applicable
                ResearchBodiesCheck(contract);

                // Check special values are not null
                if (contract.contractType == null)
                {
                    foreach (KeyValuePair <string, DataValueInfo> pair in dataValues)
                    {
                        // Only check if it is a required value
                        if (pair.Value.required)
                        {
                            CheckRequiredValue(pair.Key);
                        }
                    }
                }

                if (contract.contractType == null || contract.ContractState == Contract.State.Generated || contract.ContractState == Contract.State.Withdrawn)
                {
                    // Check for unique values against other contracts of the same type
                    foreach (KeyValuePair <string, DataNode.UniquenessCheck> pair in uniquenessChecks.Where(p => contract.uniqueData.ContainsKey(p.Key)))
                    {
                        string key = pair.Key;
                        DataNode.UniquenessCheck uniquenessCheck = pair.Value;

                        LoggingUtil.LogVerbose(this, "Doing unique value check for " + key);

                        // Get the active/offered contract lists
                        IEnumerable <ConfiguredContract> contractList = ConfiguredContract.CurrentContracts.
                                                                        Where(c => c != null && c.contractType != null && c != contract);

                        // Add in finished contracts
                        if (uniquenessCheck == DataNode.UniquenessCheck.CONTRACT_ALL || uniquenessCheck == DataNode.UniquenessCheck.GROUP_ALL)
                        {
                            contractList = contractList.Union(ContractSystem.Instance.ContractsFinished.OfType <ConfiguredContract>().
                                                              Where(c => c != null && c.contractType != null && c != contract));
                        }

                        // Filter anything that doesn't have our key
                        contractList = contractList.Where(c => c.uniqueData.ContainsKey(key));

                        // Check for contracts of the same type
                        if (uniquenessCheck == DataNode.UniquenessCheck.CONTRACT_ALL || uniquenessCheck == DataNode.UniquenessCheck.CONTRACT_ACTIVE)
                        {
                            contractList = contractList.Where(c => c.contractType.name == name);
                        }
                        // Check for a shared group
                        else if (contractType.group != null)
                        {
                            contractList = contractList.Where(c => c.contractType.group != null && c.contractType.group.name == contractType.group.name);
                        }
                        // Shared lack of group
                        else
                        {
                            contractList = contractList.Where(c => c.contractType.group == null);
                        }

                        object val = contract.uniqueData[key];
                        if (val != null)
                        {
                            // Special case for vessels - convert to the Guid
                            Vessel vessel = val as Vessel;
                            if (vessel != null)
                            {
                                val = vessel.id;
                            }

                            foreach (ConfiguredContract otherContract in contractList)
                            {
                                if (val.Equals(otherContract.uniqueData[key]))
                                {
                                    throw new ContractRequirementException("Failed on unique value check for key '" + key + "'.");
                                }
                            }
                        }
                    }
                }

                // Check the captured requirements
                if (!ContractRequirement.RequirementsMet(contract, this, contract.requirements != null ? contract.requirements : requirements))
                {
                    throw new ContractRequirementException("Failed on contract requirement check.");
                }

                return(true);
            }
            catch (ContractRequirementException e)
            {
                LoggingUtil.LogLevel level = contract.ContractState == Contract.State.Active ? LoggingUtil.LogLevel.INFO : contract.contractType != null ? LoggingUtil.LogLevel.DEBUG : LoggingUtil.LogLevel.VERBOSE;
                string prefix = contract.contractType != null ? "Cancelling contract of type " + name + " (" + contract.Title + "): " :
                                "Didn't generate contract of type " + name + ": ";
                LoggingUtil.Log(level, this.GetType(), prefix + e.Message);
                return(false);
            }
            catch
            {
                LoggingUtil.LogError(this, "Exception while attempting to check requirements of contract type " + name);
                throw;
            }
            finally
            {
                LoggingUtil.logLevel = origLogLevel;
                loaded = true;
            }
        }
예제 #4
0
        /// <summary>
        /// Tests whether a contract can be offered.
        /// </summary>
        /// <param name="contract">The contract</param>
        /// <returns>Whether the contract can be offered.</returns>
        public bool MeetRequirements(ConfiguredContract contract)
        {
            // Hash check
            if (contract.ContractState == Contract.State.Offered && contract.hash != hash)
            {
                LoggingUtil.LogDebug(this, "Cancelling offered contract of type " + name + ", contract definition changed.");
                return(false);
            }

            // Check prestige
            if (prestige.Count > 0 && !prestige.Contains(contract.Prestige))
            {
                LoggingUtil.LogVerbose(this, "Didn't generate contract type " + name + ", wrong prestige level.");
                return(false);
            }

            // Checks for maxSimultaneous/maxCompletions
            if (maxSimultaneous != 0 || maxCompletions != 0)
            {
                // Get the count of active contracts - excluding ours
                int activeContracts = ContractSystem.Instance.GetCurrentContracts <ConfiguredContract>().
                                      Count(c => c.contractType != null && c.contractType.name == name);
                if (contract.ContractState == Contract.State.Offered || contract.ContractState == Contract.State.Active)
                {
                    activeContracts--;
                }

                // Check if we're breaching the active limit
                if (maxSimultaneous != 0 && activeContracts >= maxSimultaneous)
                {
                    LoggingUtil.LogVerbose(this, "Didn't generate contract type " + name + ", too many active contracts.");
                    return(false);
                }

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

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

            // Check special values are not null
            if (contract.ContractState != Contract.State.Active)
            {
                foreach (KeyValuePair <string, bool> pair in dataValues)
                {
                    // Only check if it is a required value
                    if (pair.Value)
                    {
                        string name = pair.Key;

                        object o = dataNode[name];
                        if (o == null)
                        {
                            LoggingUtil.LogVerbose(this, "Didn't generate contract type " + this.name + ", '" + name + "' was null.");
                            return(false);
                        }
                        else if (o == typeof(List <>))
                        {
                            PropertyInfo prop  = o.GetType().GetProperty("Count");
                            int          count = (int)prop.GetValue(o, null);
                            if (count == 0)
                            {
                                LoggingUtil.LogVerbose(this, "Didn't generate contract type " + this.name + ", '" + name + "' had zero count.");
                                return(false);
                            }
                        }
                        else if (o == typeof(Vessel))
                        {
                            Vessel v = (Vessel)o;

                            if (v.state == Vessel.State.DEAD)
                            {
                                LoggingUtil.LogVerbose(this, "Didn't generate contract type " + this.name + ", vessel '" + v.vesselName + "' is dead.");
                                return(false);
                            }
                        }
                    }
                }
            }

            // Check the captured requirements
            return(ContractRequirement.RequirementsMet(contract, this, requirements));
        }