Пример #1
0
        /// <summary>
        /// Analyzes an attribute and returns whether or not it is valid.
        /// </summary>
        /// <param name="character">The character to analyze.</param>
        /// <param name="attribute">The characters attribute to check.</param>
        /// <param name="dependency">The dependency to check with.</param>
        /// <returns>A string array containing useful error messages. If empty, no errors were found.</returns>
        public static string[] ValidateAttribute(Character character, NumAttribute attribute)
        {
            List <string> errors = new List <string>();

            attribute.setMax(FindHighestPossible(character, attribute));
            attribute.setMin(FindLowestPossible(character, attribute));
            if (attribute.getMax() < attribute.getMin())
            {
                errors.Add(attribute.Name + " has a higher minimum value than its maximum value, meaning it can never be correct.");
            }
            foreach (NumDependency d in attribute.Dependancies)
            {
                if (d.type == Operand.QuotiantOf)
                {
                    if (d.v2IsRef)
                    {
                        if (Zeroable(character, (NumAttribute)character.Attributes[d.v2Ref]))
                        {
                            errors.Add(attribute.Name + " is derived by dividing by zero, or could potentially be derived by dividing by zero.\n" +
                                       "Ensure that no attributes depended upon by " + attribute.Name + " can potentially be zero.");
                        }
                    }
                    else if (d.Value2 == 0)
                    {
                        errors.Add(attribute.Name + " is derived by dividing by zero, or could potentially be derived by dividing by zero.\n" +
                                   "Ensure that no attributes depended upon by " + attribute.Name + " can potentially be zero.");
                    }
                }
            }
            return(errors.ToArray());
        }
Пример #2
0
        /// <summary>
        /// Takes an instance of character and a specific attribute within that character, and returns the highest value that attribute can potentially have.
        /// </summary>
        /// <param name="character">The instance of character your attribute is stored within.</param>
        /// <param name="attribute">The attribute you are validating</param>
        /// <returns>The highest number the attribute is allowed to be based on its dependencies</returns>
        private static decimal FindHighestPossible(Character character, NumAttribute attribute)
        {
            decimal highestPossible = decimal.MaxValue;

            //This method is recursive. To save on memory, if it runs once it'll store the value it returns in the attribute's max value.
            //If this method is called on an attribute it has already been called on, it will simply return the already stored max value.
            //In order to ensure we can validate attributes when a player updates them, we should set max and min values to null in any attribute that is edited.
            if (attribute.getMax() != null)
            {
                highestPossible = (decimal)attribute.getMax();
            }
            else
            {
                foreach (NumDependency d in attribute.Dependancies)
                {
                    // >Inb4 longest switch statement I've ever written.
                    // >It's super ugly, but super functional.
                    // >I feel fulfilled and disgusted simultaneously
                    // >Mfw: http://i.imgur.com/c65CEFK.png
                    switch (d.type)
                    {
                    case Operand.Equals:
                        if (d.v1IsRef)
                        {
                            highestPossible = FindHighestPossible(character, (NumAttribute)character.Attributes[d.v1Ref]);
                        }
                        else
                        {
                            highestPossible = d.Value1;
                        }
                        attribute.setMax(highestPossible);
                        break;

                    case Operand.DifferenceOf:
                        decimal x = d.v1IsRef ? FindHighestPossible(character, (NumAttribute)character.Attributes[d.v1Ref]) : d.Value1;
                        decimal y = d.v2IsRef ? FindHighestPossible(character, (NumAttribute)character.Attributes[d.v2Ref]) : d.Value2;
                        highestPossible = x - y;
                        attribute.setMax(highestPossible);
                        break;

                    case Operand.LessThan:
                    case Operand.LessOrEqualTo:
                        if (d.v1IsRef)
                        {
                            NumAttribute n = (NumAttribute)character.Attributes[d.v1Ref];
                            highestPossible = FindHighestPossible(character, (NumAttribute)character.Attributes[d.v1Ref]) - (d.type == Operand.LessOrEqualTo ? 0 : 1);
                        }
                        else
                        {
                            highestPossible = d.Value1 - (d.type == Operand.LessOrEqualTo ? 0 : 1);
                        }
                        break;

                    case Operand.ProductOf:
                        x = d.v1IsRef ? FindHighestPossible(character, (NumAttribute)character.Attributes[d.v1Ref]) : d.Value1;
                        y = d.v2IsRef ? FindHighestPossible(character, (NumAttribute)character.Attributes[d.v2Ref]) : d.Value2;
                        highestPossible = x * y;
                        attribute.setMax(highestPossible);
                        break;

                    case Operand.QuotiantOf:
                        x = d.v1IsRef ? FindHighestPossible(character, (NumAttribute)character.Attributes[d.v1Ref]) : d.Value1;
                        y = d.v2IsRef ? FindHighestPossible(character, (NumAttribute)character.Attributes[d.v2Ref]) : d.Value2;
                        highestPossible = x / y;
                        attribute.setMax(highestPossible);
                        break;

                    case Operand.SumOf:
                        x = d.v1IsRef ? FindHighestPossible(character, (NumAttribute)character.Attributes[d.v1Ref]) : d.Value1;
                        y = d.v2IsRef ? FindHighestPossible(character, (NumAttribute)character.Attributes[d.v2Ref]) : d.Value2;
                        highestPossible = x + y;
                        attribute.setMax(highestPossible);
                        break;
                    }
                }
            }
            attribute.setMax(highestPossible);
            return(highestPossible);
        }