Example #1
0
        /// <summary>
        /// Gets the amount of damage, healing, and crit chance/damage a status effect does as a list of key value pairs.
        /// </summary>
        /// <param name="character">The character to use to calculate the amount of damage and healing a status effect does.</param>
        /// <param name="status">The status effect to get data for.</param>
        /// <returns>A list of key value pairs containing the name of the stat and the value of that stat.</returns>
        private List <KeyValuePair <string, int> > GetStatusDamageData(Character character, StatusEffect status)
        {
            var data = new List <KeyValuePair <string, int> >();

            var damage = GetElementalData(DamageCalculator.GetDamage(character, status), "Damage/Turn");
            // Calculate heals
            int  healAmount    = DamageCalculator.GetHealing(character, status);
            int  healPercent   = DamageCalculator.GetHealingPercentage(character, status);
            bool healsOrDamage = damage.Any() || healAmount != 0 || healPercent != 0;

            // Add damage first
            data.AddRange(damage);

            if (healsOrDamage)
            {
                data.Add(new KeyValuePair <string, int>("Crit Chance", status.DamageCritChance + character.CritChance));
                data.Add(new KeyValuePair <string, int>("Crit Damage", status.DamageCritMultiplier + character.CritMultiplier));
            }

            // Add any healing amounts
            if (healAmount != 0)
            {
                data.Add(new KeyValuePair <string, int>("Health Restored/Turn", healAmount));
            }
            if (healPercent != 0)
            {
                data.Add(new KeyValuePair <string, int>("% Health Restored/Turn", healPercent));
            }

            return(data);
        }
Example #2
0
        /// <summary>
        /// Gets all possible actions for the active character and splits them into offensive and defensive actions,
        /// giving each a priority based on the amount of healing, damage, and/or ai weight provided by the action.
        /// </summary>
        /// <returns>A struct providing the action priorities of offensive and defensive actions.</returns>
        protected virtual ActionPriorities EvaluateActions()
        {
            var defensiveActionsPoints    = new Dictionary <ActionBase, int>();
            var offensiveActionsPoints    = new Dictionary <ActionBase, int>();
            var defensiveActionPriorities = new Dictionary <ActionBase, int>();
            var offensiveActionPriorities = new Dictionary <ActionBase, int>();
            var allActions = new List <ActionBase>();

            allActions.AddRange(_activeCharacter.Attacks);
            allActions.AddRange(_activeCharacter.SpellList);
            allActions.AddRange(_activeCharacter.SkillList);
            var consumables = _activeCharacter.Inventory
                              .Where(item => item is Consumable)
                              .Select(item => ((Consumable)item).ItemSpell);

            allActions.AddRange(consumables);

            // Use average max health as basis for effectiveness of damage and healing
            int averageMaxHealth = 0;

            foreach (var character in AICharacters)
            {
                averageMaxHealth += character.CurrentMaxHealth;
            }
            averageMaxHealth /= AICharacters.Count();

            // Calculate total healing and damage and use it to determine if an action is offensive or defensive
            foreach (var action in allActions)
            {
                int damage         = DamageCalculator.GetDamageAsInt(_activeCharacter, action);
                int healing        = DamageCalculator.GetHealing(_activeCharacter, action);
                int percentHealing = DamageCalculator.GetHealingPercentage(_activeCharacter, action);

                int netDamage = damage - healing;

                if (netDamage < 0 || percentHealing > 0 || !action.IsOffensive)
                {
                    int maxPotential = -netDamage;
                    maxPotential += (percentHealing * averageMaxHealth / 100);
                    defensiveActionsPoints[action] = maxPotential;
                }
                else
                {
                    int maxPotential = netDamage;
                    offensiveActionsPoints[action] = maxPotential;
                }
            }

            int medianHealing = MathExtensions.GetMedian(defensiveActionsPoints.Values.ToList());
            int medianDamage  = MathExtensions.GetMedian(offensiveActionsPoints.Values.ToList());

            // Assign action priorities based on how an action performs on par with other actions

            foreach (var key in defensiveActionsPoints.Keys)
            {
                int healing = defensiveActionsPoints[key];
                defensiveActionPriorities[key] = key.AiWeight;
                if (medianHealing > 0)
                {
                    if (PercentageCalculator.GetPercentage(healing, medianHealing) >= 150)
                    {
                        defensiveActionPriorities[key] += 3;
                    }
                    else if (PercentageCalculator.GetPercentage(healing, medianHealing) >= 120)
                    {
                        defensiveActionPriorities[key] += 2;
                    }
                }
                else
                {
                    defensiveActionPriorities[key] += 1;
                }
            }

            foreach (var key in offensiveActionsPoints.Keys)
            {
                int damage = offensiveActionsPoints[key];
                offensiveActionPriorities[key] = key.AiWeight;
                if (medianDamage > 0)
                {
                    if (PercentageCalculator.GetPercentage(damage, medianDamage) >= 150)
                    {
                        offensiveActionPriorities[key] += 3;
                    }
                    else if (PercentageCalculator.GetPercentage(damage, medianDamage) >= 120)
                    {
                        offensiveActionPriorities[key] += 2;
                    }
                }
                else
                {
                    offensiveActionPriorities[key] += 1;
                }
            }

            return(new ActionPriorities()
            {
                DefensiveActionPriorities = defensiveActionPriorities,
                OffensiveActionPriorities = offensiveActionPriorities
            });
        }