Beispiel #1
0
        public BestTargetResult GetBestTargets(uint battleId, ICombatObject attacker, out List <Target> result, int maxCount, uint round)
        {
            result = new List <Target>();

            var objectsByScore = new List <CombatScoreItem>(Count);

            var objsInRange = (from combatGroup in this
                               from defender in combatGroup
                               where !defender.IsWaitingToJoinBattle &&
                               !defender.IsDead &&
                               defender.InRange(attacker) &&
                               attacker.InRange(defender)
                               select new Target {
                Group = combatGroup, CombatObject = defender
            }).ToList();

            if (objsInRange.Count == 0)
            {
                return(BestTargetResult.NoneInRange);
            }

            uint lowestRow = objsInRange.Min(target => target.CombatObject.Stats.Stl);

            Target  bestTarget      = null;
            decimal bestTargetScore = 0;

            foreach (var target in objsInRange)
            {
                if (!attacker.CanSee(target.CombatObject, lowestRow))
                {
                    continue;
                }

                // Calculate dmg against each target as base score
                decimal score = battleFormulas.GetAttackScore(attacker, target.CombatObject, round);

                if (bestTarget == null || score > bestTargetScore)
                {
                    bestTarget      = target;
                    bestTargetScore = score;
                }

                objectsByScore.Add(new CombatScoreItem {
                    Target = target, Score = score
                });
            }

            if (objectsByScore.Count == 0)
            {
                return(BestTargetResult.Ok);
            }

            // Shuffle to get some randomization in the attack order. We pass the battleId as a seed in order to
            // make it so the attacker doesn't switch targets once it starts attacking them but this way
            // they won't attack the stacks in the order they joined the battle, which usually would mean
            // they will attack the same type of units one after another
            // then sort by score descending
            var shuffled = objectsByScore.Shuffle((int)battleId);

            shuffled.Sort(new CombatScoreItemComparer(attacker, tileLocator));

            var numberOfTargetsToHit = Math.Min(maxCount, objectsByScore.Count);

            // Get top results specified by the maxCount param
            result = shuffled.Take(numberOfTargetsToHit).Select(scoreItem => scoreItem.Target).ToList();

            return(BestTargetResult.Ok);
        }
Beispiel #2
0
 public bool HasInRange(ICombatObject attacker)
 {
     return(AllAliveCombatObjects().Any(obj => obj.InRange(attacker) && attacker.InRange(obj)));
 }