Example #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());
        }
Example #2
0
        /// <summary>
        /// This method is called upon an attribute to check all of its referenced attributes, and make sure no circular logic is present.
        /// </summary>
        /// <param name="character">The character the attribute you are checking is stored in.</param>
        /// <param name="attribute">The attribute you are checking</param>
        /// <param name="referenced">All attributes which have already been checked in the line of recursion.</param>
        /// <returns>A string[] containing all attributes the checked attribute relies on which resulted in circular logic.</returns>
        private static string[] CheckCircularReferences(Character character, NumAttribute attribute, List <NumAttribute> alreadyChecked = null)
        {
            List <string> referenceErrors = new List <string>();

            //Initialize the alreadyChecked list if this is the first instance of this method to be called per recursive line.
            if (alreadyChecked == null)
            {
                alreadyChecked = new List <NumAttribute>();
            }
            //Add the current attribute to the list of checked attributes. That list will be used to make sure an attribute doesn't reference itself, even indirectly.
            alreadyChecked.Add(attribute);
            foreach (NumDependency d in attribute.Dependancies)
            {
                if (d.v1IsRef)
                {
                    if (alreadyChecked.Contains(character.Attributes[d.v1Ref]))
                    {
                    }
                }
                if (d.v2IsRef)
                {
                }
            }
            return(referenceErrors.ToArray());
        }
Example #3
0
        private void Atribute_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            words.Content = "";
            NumAttribute a = new NumAttribute(null, null, 0, null);

            a = (NumAttribute)MainEngine.Template.Attributes.Values.ElementAt(Atribute.SelectedIndex);
            for (int i = 0; i < a.Dependancies.Count; i++)
            {
                words.Content += (a.Dependancies[i].ToString() + "\n");
            }
        }
Example #4
0
        public NewCharacter()
        {
            InitializeComponent();
            List <NumDependency> L = new List <NumDependency>();
            NumAttribute         n = new NumAttribute("Strength", null, 0, L);
            NumDependency        d = new NumDependency(Operand.GreaterThan, true, true, n, 0);

            L.Add(d);
            MainEngine.Template.Attributes.Add(n.Name, n);
            Atribute.ItemsSource = MainEngine.Template.Attributes.Keys;
        }
Example #5
0
        private void SaveValue_Click(object sender, RoutedEventArgs e)
        {
            NumAttribute a = new NumAttribute(null, null, 0, null);
            decimal      d = 0;

            a = (NumAttribute)MainEngine.Template.Attributes.Values.ElementAt(Atribute.SelectedIndex);
            if (decimal.TryParse(valuebox.Text, out d))
            {
                a.Value = d;
            }
            else
            {
                a.Name = valuebox.Text;
            }
        }
Example #6
0
        /// <summary>
        /// Checks an attribute to see if it is ever possible for it to be zero. Useful for knowing if it is always safe to divide by this attribute.
        /// </summary>
        /// <param name="character">The character the checked attribute is stored within.</param>
        /// <param name="attribute">The attribute you are checking.</param>
        /// <returns>Whether or not the attribute can ever, for any reason, at any time, be zero.</returns>
        private static bool Zeroable(Character character, NumAttribute attribute)
        {
            bool zeroable = true;

            if (attribute.Zeroable != null)
            {
                zeroable = (bool)attribute.Zeroable;
            }
            else
            {
                if (FindHighestPossible(character, attribute) >= 0 && FindLowestPossible(character, attribute) <= 0)
                {
                    zeroable = true;
                }
            }
            attribute.Zeroable = zeroable;
            return(zeroable);
        }
        private void SaveAttribute_Click(object sender, RoutedEventArgs e)
        {
            if (!CharacterEngine.CharTemplate.Attributes.ContainsKey(AttributeNameField.Text))
            {
                switch (AttributeType.SelectedIndex)
                {
                case 0:                         //Text
                    CharacterEngine.CharTemplate.Attributes.Add(AttributeNameField.Text, new TextAttribute(AttributeNameField.Text, "", 0, ""));
                    break;

                case 1:                         //Number
                    NumAttribute newAttribute = new NumAttribute(AttributeNameField.Text, "", 0, dependencies);
                    string[]     errors       = CharacterEngine.ValidateAttribute(CharacterEngine.CharTemplate, newAttribute);

                    if (errors.Length == 0)
                    {
                        CharacterEngine.CharTemplate.Attributes.Add(newAttribute.Name, newAttribute);
                    }
                    else
                    {
                        StringBuilder consolodatedErrors = new StringBuilder();

                        foreach (string error in errors)
                        {
                            consolodatedErrors.Append(error + "\n");
                        }
                        MessageBoxResult errorMessage = MessageBox.Show(consolodatedErrors.ToString());
                    }
                    break;

                case 2:                         //Bool
                    CharacterEngine.CharTemplate.Attributes.Add(AttributeNameField.Text, new BoolAttribute(AttributeNameField.Text, "", 0));
                    break;
                }
            }
            else
            {
                AttributeNameField.Text = "Name Already In Use";
            }
        }
 public OffensiveItem(string name, string description) : base(name, description)
 {
     List <NumDependency> nl = new List <NumDependency>();
     NumAttribute         n  = new NumAttribute("Attack", "1", 1, nl);
 }
Example #9
0
        /// <summary>
        /// Takes an instance of character and a specific attribute within that character, and returns the lowest 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 lowest number the attribute is allowed to be based on its dependencies</returns>
        private static decimal FindLowestPossible(Character character, NumAttribute attribute)
        {
            decimal lowestPossible = -decimal.MaxValue;

            if (attribute.getMin() != null)
            {
                lowestPossible = (decimal)attribute.getMin();
            }
            else
            {
                foreach (NumDependency d in attribute.Dependancies)
                {
                    switch (d.type)
                    {
                    case Operand.Equals:
                        if (d.v1IsRef)
                        {
                            lowestPossible = FindLowestPossible(character, (NumAttribute)character.Attributes[d.v1Ref]);
                        }
                        else
                        {
                            lowestPossible = d.Value1;
                        }
                        attribute.setMin(lowestPossible);
                        break;

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

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

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

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

                    case Operand.SumOf:
                        x = d.v1IsRef ? FindLowestPossible(character, (NumAttribute)character.Attributes[d.v1Ref]) : d.Value1;
                        y = d.v2IsRef ? FindLowestPossible(character, (NumAttribute)character.Attributes[d.v2Ref]) : d.Value2;
                        lowestPossible = x + y;
                        attribute.setMin(lowestPossible);
                        break;
                    }
                }
            }
            attribute.setMin(lowestPossible);
            return(lowestPossible);
        }
Example #10
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);
        }