Example #1
0
        public AISpellCastPossibility FindFirstSpellCast()
        {
            var casts     = new List <AISpellCastPossibility>();
            var minUsedAP = 0;
            var minUsedPM = 0;

            foreach (var priority in Priorities.OrderByDescending(x => x.Value))
            {
                // find best spell
                var impactComparer = new SpellImpactComparer(this, priority.Key);
                foreach (var possibleCast in Possibilities.OrderByDescending(x => x, new SpellCastComparer(this, priority.Key)))
                {
                    var category = SpellIdentifier.GetSpellCategories(possibleCast.Spell);

                    var dummy = possibleCast;
                    if ((category & priority.Key) == 0 || casts.Any(x => x.Spell == dummy.Spell))   // spell already used
                    {
                        continue;
                    }

                    if (Fighter.AP - minUsedAP < possibleCast.Spell.CurrentSpellLevel.ApCost)
                    {
                        continue;
                    }

                    if (possibleCast.IsSummoningSpell)
                    {
                        var target = new SpellTarget()
                        {
                            Target = new TargetCell(possibleCast.SummonCell), CastCell = Fighter.Cell, AffectedCells = new [] { possibleCast.SummonCell }
                        };
                        casts.Add(new AISpellCastPossibility(possibleCast.Spell, target));
                        minUsedAP += (int)possibleCast.Spell.CurrentSpellLevel.ApCost;
                        continue;
                    }

                    // find best target
                    foreach (var impact in possibleCast.Impacts.OrderByDescending(x => x, impactComparer))
                    {
                        if (impactComparer.GetScore(impact) <= 0)
                        {
                            continue;
                        }

                        Cell castSpell = impact.CastCell;

                        var cast = new AISpellCastPossibility(possibleCast.Spell, impact);
                        if (castSpell == Fighter.Cell)
                        {
                            casts.Add(cast);
                            minUsedAP += (int)possibleCast.Spell.CurrentSpellLevel.ApCost;
                            continue;
                        }

                        var pathfinder = new Pathfinder(m_environment.CellInformationProvider);
                        var path       = pathfinder.FindPath(Fighter.Position.Cell.Id, castSpell.Id, false);

                        if (path.IsEmpty() || path.MPCost > Fighter.MP)
                        {
                            continue;
                        }

                        cast.MoveBefore = path;

                        casts.Add(cast);
                        minUsedAP += (int)possibleCast.Spell.CurrentSpellLevel.ApCost;
                        minUsedPM += path.MPCost;
                        break;
                    }
                }
            }

            if (casts.Count > 1)
            {
                // check if the second spell can be casted before
                var max = MaxConsecutiveSpellCast(casts[0].Spell, Fighter.AP);
                if (casts[1].Spell.CurrentSpellLevel.ApCost <= Fighter.AP - max * casts[0].Spell.CurrentSpellLevel.ApCost &&
                    casts[0].MoveBefore != null)
                {
                    if (casts[1].MoveBefore == null)
                    {
                        return(casts[1]);
                    }

                    var pathfinder = new Pathfinder(m_environment.CellInformationProvider);
                    var path       = pathfinder.FindPath(casts[1].MoveBefore.EndCell.Id, casts[0].MoveBefore != null ? casts[0].MoveBefore.EndCell.Id : Fighter.Cell.Id, false);

                    if (!path.IsEmpty() && path.MPCost + casts[1].MPCost <= Fighter.MP)
                    {
                        return(casts[1]);
                    }
                }
            }

            return(casts.FirstOrDefault());
        }
Example #2
0
        public IEnumerable <SpellCast> EnumerateSpellsCast()
        {
            Func <MapPoint, uint> keySelector = null;

            foreach (KeyValuePair <SpellCategory, int> iteratorVariable0 in from x in this.Priorities
                     orderby x.Value descending
                     select x)
            {
                SpellImpactComparer comparer = new SpellImpactComparer(this, iteratorVariable0.Key);
                foreach (SpellCastInformations iteratorVariable2 in this.Possibilities.OrderBy <SpellCastInformations, SpellCastInformations>(x => x, new SpellCastComparer(this, iteratorVariable0.Key)))
                {
                    SpellCategory spellCategories = SpellIdentifier.GetSpellCategories(iteratorVariable2.Spell);
                    if ((spellCategories & ((SpellCategory)iteratorVariable0.Key)) != SpellCategory.None)
                    {
                        if (this.Fighter.AP == 0)
                        {
                            break;
                        }
                        if (iteratorVariable2.MPToUse <= this.Fighter.MP)
                        {
                            if (iteratorVariable2.IsSummoningSpell)
                            {
                                yield return(new SpellCast(iteratorVariable2.Spell, iteratorVariable2.SummonCell));
                            }
                            else
                            {
                                foreach (SpellTarget iteratorVariable4 in iteratorVariable2.Impacts.OrderByDescending <SpellTarget, SpellTarget>(x => x, comparer))
                                {
                                    int iteratorVariable5;
                                    if (this.CanReach(iteratorVariable4.Target, iteratorVariable2.Spell, out iteratorVariable5))
                                    {
                                        SpellCast iteratorVariable6 = new SpellCast(iteratorVariable2.Spell, iteratorVariable4.Target.Cell);
                                        if (iteratorVariable5 == 0)
                                        {
                                            yield return(iteratorVariable6);
                                        }
                                        else if (iteratorVariable5 <= this.Fighter.MP)
                                        {
                                            if (keySelector == null)
                                            {
                                                keySelector = entry => entry.DistanceToCell(this.Fighter.Position.Point);
                                            }
                                            MapPoint point = iteratorVariable4.Target.Position.Point.GetAdjacentCells(new Func <short, bool>(this.m_environment.CellInformationProvider.IsCellWalkable)).OrderBy <MapPoint, uint>(keySelector).FirstOrDefault <MapPoint>();
                                            if (point == null)
                                            {
                                                point = iteratorVariable4.Target.Position.Point;
                                            }
                                            Path iteratorVariable9 = new Pathfinder(this.m_environment.CellInformationProvider).FindPath(this.Fighter.Position.Cell.Id, point.CellId, false, this.Fighter.MP);
                                            if (!iteratorVariable9.IsEmpty() && (iteratorVariable9.MPCost <= this.Fighter.MP))
                                            {
                                                iteratorVariable6.MoveBefore = iteratorVariable9;
                                                yield return(iteratorVariable6);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }