Пример #1
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
            });
        }