Пример #1
0
        public bool GetRangeAttack(out int min, out int max)
        {
            bool hasRangeAttack = false;

            min = 0;
            max = 0;
            foreach (var spell in Fighter.Spells.Values)
            {
                var category = SpellIdentifier.GetSpellCategories(spell);
                if ((category & SpellCategory.Damages) != 0)
                {
                    if (min < spell.CurrentSpellLevel.MinRange)
                    {
                        min = (int)spell.CurrentSpellLevel.MinRange;
                    }

                    if (spell.CurrentSpellLevel.Range > max)
                    {
                        max = (int)spell.CurrentSpellLevel.Range;
                    }

                    hasRangeAttack = true;
                }
            }

            return(hasRangeAttack);
        }
Пример #2
0
        public int MaxConsecutiveSpellCast(Spell spell, int ap)
        {
            // can be casted indefinitly
            if (spell.CurrentSpellLevel.ApCost == 0 && spell.CurrentSpellLevel.MinCastInterval == 0)
            {
                return(0);
            }

            if (spell.CurrentSpellLevel.GlobalCooldown > 0)
            {
                return(1);
            }

            var max      = (int)(ap / spell.CurrentSpellLevel.ApCost);
            var category = SpellIdentifier.GetSpellCategories(spell);

            if ((category & SpellCategory.Summoning) != 0)
            {
                return(1);
            }

            if (spell.CurrentSpellLevel.MaxCastPerTarget > 0 &&
                max > spell.CurrentSpellLevel.MaxCastPerTarget)
            {
                max = (int)spell.CurrentSpellLevel.MaxCastPerTarget;
            }

            if (spell.CurrentSpellLevel.MaxCastPerTurn > 0 &&
                max > spell.CurrentSpellLevel.MaxCastPerTurn)
            {
                max = (int)spell.CurrentSpellLevel.MaxCastPerTurn;
            }

            return(max);
        }
 public static SpellCategory GetSpellCategories(Spell spell)
 {
     return(spell.CurrentSpellLevel.Effects.Aggregate(SpellCategory.None, (SpellCategory current, EffectDice effect) => current | SpellIdentifier.GetEffectCategories(effect.EffectId)));
 }
Пример #4
0
        // todo : do something more general (ghost actors)
        private void CumulEffects(SpellEffectHandler handler, ref SpellTarget spellImpact, FightActor target, Spell spell)
        {
            var effect   = handler.Dice;
            var isFriend = Fighter.Team.Id == target.Team.Id;
            var result   = new SpellTarget();

            var category = SpellIdentifier.GetEffectCategories(effect.EffectId);

            if (category == 0)
            {
                return;
            }

            if (Fighter is SummonedTurret)
            {
                isFriend = category == SpellCategory.Healing;
            }

            var chanceToHappen = 1.0; //

            // When chances to happen is under 100%, then we reduce spellImpact accordingly, for simplicity, but after having apply damage bonus & reduction.
            // So average damage should remain exact even if Min and Max are not.
            if (effect.Random > 0)
            {
                chanceToHappen = effect.Random / 100.0;
            }

            if ((target is SummonedFighter))
            {
                chanceToHappen /= 2; // It's much better to hit non-summoned foes => effect on summons (except allies summon for Osa) is divided by 2.
            }
            uint min;
            uint max;

            if (handler is DamagePerHPLost)
            {
                min = max = (uint)Math.Round(((Fighter.Stats.Health.DamageTaken * effect.DiceNum) / 100d));
            }
            else if (handler is Kill && target != Fighter) // doesn't take sacrifice in account
            {
                min = max = (uint)target.LifePoints;
            }
            else
            {
                min = (uint)Math.Min(effect.DiceNum, effect.DiceFace);
                max = (uint)Math.Max(effect.DiceNum, effect.DiceFace);
            }

            if ((category & SpellCategory.DamagesNeutral) > 0)
            {
                AdjustDamage(result, min, max, SpellCategory.DamagesNeutral, chanceToHappen,
                             Fighter.Stats.GetTotal(PlayerFields.NeutralDamageBonus) + Fighter.Stats.GetTotal(PlayerFields.DamageBonus) + Fighter.Stats.GetTotal(PlayerFields.PhysicalDamage),
                             Fighter.Stats.GetTotal(PlayerFields.DamageBonusPercent) + Fighter.Stats.GetTotal(PlayerFields.Strength),
                             target.Stats.GetTotal(PlayerFields.NeutralElementReduction),
                             target.Stats.GetTotal(PlayerFields.NeutralResistPercent),
                             isFriend);
            }

            if ((category & SpellCategory.DamagesFire) > 0)
            {
                AdjustDamage(result, min, max, SpellCategory.DamagesNeutral, chanceToHappen,
                             Fighter.Stats.GetTotal(PlayerFields.FireDamageBonus) + Fighter.Stats.GetTotal(PlayerFields.DamageBonus) + Fighter.Stats.GetTotal(PlayerFields.MagicDamage),
                             Fighter.Stats.GetTotal(PlayerFields.DamageBonusPercent) + Fighter.Stats.GetTotal(PlayerFields.Intelligence),
                             target.Stats.GetTotal(PlayerFields.FireElementReduction),
                             target.Stats.GetTotal(PlayerFields.FireResistPercent),
                             isFriend);
            }


            if ((category & SpellCategory.DamagesAir) > 0)
            {
                AdjustDamage(result, min, max, SpellCategory.DamagesNeutral, chanceToHappen,
                             Fighter.Stats.GetTotal(PlayerFields.AirDamageBonus) + Fighter.Stats.GetTotal(PlayerFields.DamageBonus) + Fighter.Stats.GetTotal(PlayerFields.MagicDamage),
                             Fighter.Stats.GetTotal(PlayerFields.DamageBonusPercent) + Fighter.Stats.GetTotal(PlayerFields.Agility),
                             target.Stats.GetTotal(PlayerFields.AirElementReduction),
                             target.Stats.GetTotal(PlayerFields.AirResistPercent),
                             isFriend);
            }

            if ((category & SpellCategory.DamagesWater) > 0)
            {
                AdjustDamage(result, min, max, SpellCategory.DamagesNeutral, chanceToHappen,
                             Fighter.Stats.GetTotal(PlayerFields.WaterDamageBonus) + Fighter.Stats.GetTotal(PlayerFields.DamageBonus) + Fighter.Stats.GetTotal(PlayerFields.MagicDamage),
                             Fighter.Stats.GetTotal(PlayerFields.DamageBonusPercent) + Fighter.Stats.GetTotal(PlayerFields.Chance),
                             target.Stats.GetTotal(PlayerFields.WaterElementReduction),
                             target.Stats.GetTotal(PlayerFields.WaterResistPercent),
                             isFriend);
            }

            if ((category & SpellCategory.DamagesEarth) > 0)
            {
                AdjustDamage(result, min, max, SpellCategory.DamagesNeutral, chanceToHappen,
                             Fighter.Stats.GetTotal(PlayerFields.EarthDamageBonus) + Fighter.Stats.GetTotal(PlayerFields.DamageBonus) + Fighter.Stats.GetTotal(PlayerFields.PhysicalDamage),
                             Fighter.Stats.GetTotal(PlayerFields.DamageBonusPercent) + Fighter.Stats.GetTotal(PlayerFields.Strength),
                             target.Stats.GetTotal(PlayerFields.EarthElementReduction),
                             target.Stats.GetTotal(PlayerFields.EarthResistPercent),
                             isFriend);
            }

            if ((category & SpellCategory.Healing) > 0)
            {
                var steal = (category & SpellCategory.Damages) > 0;
                if (steal)
                {
                    target = Fighter;                                                         // Probably hp steal
                }
                var hptoHeal = (uint)(Math.Max(0, target.MaxLifePoints - target.LifePoints)); // Can't heal over max
                if (steal)
                {
                    result.MinHeal = Math.Min(hptoHeal, Math.Abs(result.MinDamage));
                    result.MaxHeal = Math.Min(hptoHeal, Math.Abs(result.MaxDamage));
                }
                else
                {
                    if (hptoHeal > 0)
                    {
                        AdjustDamage(result, (uint)Math.Min(effect.DiceNum, hptoHeal), (uint)Math.Min(effect.DiceFace, hptoHeal), SpellCategory.Healing, chanceToHappen,
                                     Fighter.Stats.GetTotal(PlayerFields.HealBonus),
                                     Fighter.Stats.GetTotal(PlayerFields.Intelligence),
                                     0,
                                     0, !isFriend);

                        if (result.Heal > hptoHeal)
                        {
                            if (isFriend)
                            {
                                result.MinHeal = result.MaxHeal = +hptoHeal;
                            }
                            else
                            {
                                result.MinHeal = result.MaxHeal = -hptoHeal;
                            }
                        }
                    }
                }
            }

            if ((category & SpellCategory.Buff) > 0)
            {
                if (isFriend)
                {
                    result.Boost += spell.CurrentLevel * chanceToHappen;
                }
                else
                {
                    result.Boost -= spell.CurrentLevel * chanceToHappen;
                }
            }

            if ((category & SpellCategory.Curse) > 0)
            {
                var ratio = spell.CurrentLevel * chanceToHappen;

                if (effect.EffectId == EffectsEnum.Effect_SkipTurn) // Let say this effect counts as 2 damage per level of the target
                {
                    ratio = target.Level * 2 * chanceToHappen;
                }

                if (isFriend)
                {
                    result.Curse -= 2 * ratio;
                }
                else
                {
                    result.Curse += ratio;
                }
            }
            if (isFriend)
            {
                result.Add(result);                                                                            // amplify (double) effects on friends.
            }
            if (!isFriend && ((category & SpellCategory.Damages) > 0) && result.MinDamage > target.LifePoints) // Enough damage to kill the target => affect an arbitrary 50% of max heal (with at least current health), so strong spells are not favored anymore.
            {
                double ratio = Math.Max(target.MaxLifePoints / 2d, target.LifePoints) / result.MinDamage;
                result.Multiply(ratio);
            }

            if (spellImpact != null)
            {
                spellImpact.Add(result);
            }
            else
            {
                spellImpact = result;
            }
        }
Пример #5
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());
        }
Пример #6
0
        public void AnalysePossibilities()
        {
            Possibilities = new List <SpellCastImpact>();
            foreach (var spell in Fighter.Spells.Values)
            {
                var category   = SpellIdentifier.GetSpellCategories(spell);
                var spellLevel = spell.CurrentSpellLevel;
                var cast       = new SpellCastImpact(spell);

                if (Fighter.AP < spellLevel.ApCost)
                {
                    continue;
                }

                if (spellLevel.StatesForbidden.Any(Fighter.HasState))
                {
                    continue;
                }

                if (spellLevel.StatesRequired.Any(state => !Fighter.HasState(state)))
                {
                    continue;
                }

                if (!Fighter.SpellHistory.CanCastSpell(spell.CurrentSpellLevel))
                {
                    continue;
                }

                // summoning is the priority
                if ((category & SpellCategory.Summoning) != 0 &&
                    ((category & SpellCategory.Healing) == 0 || Fighter.Team.Fighters.Any(x => x.IsDead())) &&                      // revive effect and an ally is dead
                    (Fighter.CanSummon() || (category & SpellCategory.Healing) != 0 && Fighter.Team.Fighters.Any(x => x.IsDead()))) // can summon or is revive spell
                {
                    var adjacentCell = Fighter.GetCastZoneSet(spell.CurrentSpellLevel, Fighter.Position.Point).EnumerateValidPoints().
                                       OrderBy(x => x.ManhattanDistanceTo(Fighter.Position.Point)).
                                       FirstOrDefault(x => m_environment.CellInformationProvider.IsCellWalkable(x.CellId));

                    if (adjacentCell == null)
                    {
                        continue;
                    }

                    cast.IsSummoningSpell = true;
                    cast.SummonCell       = Fighter.Map.Cells[adjacentCell.CellId];
                }
                else
                {
                    var cells =
                        ExpandCellsZone(Fighter.Fight.Fighters.Where(fighter => fighter.IsAlive() && fighter.IsVisibleFor(Fighter))
                                        .Select(x => x.Cell).ToArray(), spell);

                    foreach (var target in cells)
                    {
                        if (!CanReach(target, spell, out var cell))
                        {
                            continue;
                        }

                        if (Fighter.CanCastSpell(new SpellCastInformations(Fighter, spell, target.Cell)
                        {
                            CastCell = cell
                        }) != SpellCastResult.OK)
                        {
                            continue;
                        }

                        var impact = ComputeSpellImpact(spell, target.Cell, cell);

                        if (impact == null)
                        {
                            continue;
                        }

                        impact.CastCell = cell;
                        impact.Target   = target;

                        if (impact.Damage < 0)
                        {
                            continue; // hurts more allies than boost them
                        }
                        cast.Impacts.Add(impact);
                    }
                }

                if (cast.Impacts.Count > 0 || cast.IsSummoningSpell)
                {
                    Possibilities.Add(cast);
                }
            }

            AnalysePossibilitiesFinished?.Invoke(Fighter);
        }
Пример #7
0
        private void CumulEffects(EffectDice effect, ref SpellTarget spellImpact, FightActor target, Spell spell)
        {
            bool            flag             = this.Fighter.Team.Id == target.Team.Id;
            SpellTarget     spellTarget      = new SpellTarget();
            SpellTargetType arg_2A_0         = effect.Targets;
            SpellCategory   effectCategories = SpellIdentifier.GetEffectCategories(effect.EffectId);

            if (effectCategories != SpellCategory.None)
            {
                double num = 1.0;
                if (effect.Random > 0)
                {
                    num = (double)effect.Random / 100.0;
                }
                if (target is SummonedFighter)
                {
                    num /= 2.0;
                }
                uint damage  = (uint)System.Math.Min(effect.DiceNum, effect.DiceFace);
                uint damage2 = (uint)System.Math.Max(effect.DiceNum, effect.DiceFace);
                if ((effectCategories & SpellCategory.DamagesNeutral) > SpellCategory.None)
                {
                    SpellSelector.AdjustDamage(spellTarget, damage, damage2, SpellCategory.DamagesNeutral, num, this.Fighter.Stats.GetTotal(PlayerFields.NeutralDamageBonus) + this.Fighter.Stats.GetTotal(PlayerFields.DamageBonus) + this.Fighter.Stats.GetTotal(PlayerFields.PhysicalDamage), this.Fighter.Stats.GetTotal(PlayerFields.DamageBonusPercent) + this.Fighter.Stats.GetTotal(PlayerFields.Strength), target.Stats.GetTotal(PlayerFields.NeutralElementReduction), target.Stats.GetTotal(PlayerFields.NeutralResistPercent), flag);
                }
                if ((effectCategories & SpellCategory.DamagesFire) > SpellCategory.None)
                {
                    SpellSelector.AdjustDamage(spellTarget, damage, damage2, SpellCategory.DamagesNeutral, num, this.Fighter.Stats.GetTotal(PlayerFields.FireDamageBonus) + this.Fighter.Stats.GetTotal(PlayerFields.DamageBonus) + this.Fighter.Stats.GetTotal(PlayerFields.MagicDamage), this.Fighter.Stats.GetTotal(PlayerFields.DamageBonusPercent) + this.Fighter.Stats.GetTotal(PlayerFields.Intelligence), target.Stats.GetTotal(PlayerFields.FireElementReduction), target.Stats.GetTotal(PlayerFields.FireResistPercent), flag);
                }
                if ((effectCategories & SpellCategory.DamagesAir) > SpellCategory.None)
                {
                    SpellSelector.AdjustDamage(spellTarget, damage, damage2, SpellCategory.DamagesNeutral, num, this.Fighter.Stats.GetTotal(PlayerFields.AirDamageBonus) + this.Fighter.Stats.GetTotal(PlayerFields.DamageBonus) + this.Fighter.Stats.GetTotal(PlayerFields.MagicDamage), this.Fighter.Stats.GetTotal(PlayerFields.DamageBonusPercent) + this.Fighter.Stats.GetTotal(PlayerFields.Agility), target.Stats.GetTotal(PlayerFields.AirElementReduction), target.Stats.GetTotal(PlayerFields.AirResistPercent), flag);
                }
                if ((effectCategories & SpellCategory.DamagesWater) > SpellCategory.None)
                {
                    SpellSelector.AdjustDamage(spellTarget, damage, damage2, SpellCategory.DamagesNeutral, num, this.Fighter.Stats.GetTotal(PlayerFields.WaterDamageBonus) + this.Fighter.Stats.GetTotal(PlayerFields.DamageBonus) + this.Fighter.Stats.GetTotal(PlayerFields.MagicDamage), this.Fighter.Stats.GetTotal(PlayerFields.DamageBonusPercent) + this.Fighter.Stats.GetTotal(PlayerFields.Chance), target.Stats.GetTotal(PlayerFields.WaterElementReduction), target.Stats.GetTotal(PlayerFields.WaterResistPercent), flag);
                }
                if ((effectCategories & SpellCategory.DamagesEarth) > SpellCategory.None)
                {
                    SpellSelector.AdjustDamage(spellTarget, damage, damage2, SpellCategory.DamagesNeutral, num, this.Fighter.Stats.GetTotal(PlayerFields.EarthDamageBonus) + this.Fighter.Stats.GetTotal(PlayerFields.DamageBonus) + this.Fighter.Stats.GetTotal(PlayerFields.PhysicalDamage), this.Fighter.Stats.GetTotal(PlayerFields.DamageBonusPercent) + this.Fighter.Stats.GetTotal(PlayerFields.Strength), target.Stats.GetTotal(PlayerFields.EarthElementReduction), target.Stats.GetTotal(PlayerFields.EarthResistPercent), flag);
                }
                if ((effectCategories & SpellCategory.Healing) > SpellCategory.None)
                {
                    bool flag2;
                    if (flag2 = ((effectCategories & SpellCategory.Damages) > SpellCategory.None))
                    {
                        target = this.Fighter;
                    }
                    uint num2 = (uint)System.Math.Max(0, target.MaxLifePoints - target.LifePoints);
                    if (flag2)
                    {
                        spellTarget.MinHeal = System.Math.Min(num2, System.Math.Abs(spellTarget.MinDamage));
                        spellTarget.MaxHeal = System.Math.Min(num2, System.Math.Abs(spellTarget.MaxDamage));
                    }
                    else
                    {
                        if (num2 > 0u)
                        {
                            SpellSelector.AdjustDamage(spellTarget, (uint)System.Math.Min((long)effect.DiceNum, (long)((ulong)num2)), (uint)System.Math.Min((long)effect.DiceFace, (long)((ulong)num2)), SpellCategory.Healing, num, this.Fighter.Stats.GetTotal(PlayerFields.HealBonus), this.Fighter.Stats.GetTotal(PlayerFields.Intelligence), 0, 0, !flag);
                            if (spellTarget.Heal > num2)
                            {
                                if (flag)
                                {
                                    spellTarget.MinHeal = (spellTarget.MaxHeal = num2);
                                }
                                else
                                {
                                    spellTarget.MinHeal = (spellTarget.MaxHeal = (double)(-(double)((ulong)num2)));
                                }
                            }
                        }
                    }
                }
                if ((effectCategories & SpellCategory.Buff) > SpellCategory.None)
                {
                    if (flag)
                    {
                        spellTarget.Boost += (double)spell.CurrentLevel * num;
                    }
                    else
                    {
                        spellTarget.Boost -= (double)spell.CurrentLevel * num;
                    }
                }
                if ((effectCategories & SpellCategory.Curse) > SpellCategory.None)
                {
                    double num3 = (double)spell.CurrentLevel * num;
                    if (effect.EffectId == EffectsEnum.Effect_SkipTurn)
                    {
                        num3 = (double)(target.Level * 2) * num;
                    }
                    if (flag)
                    {
                        spellTarget.Curse -= 2.0 * num3;
                    }
                    else
                    {
                        spellTarget.Curse += num3;
                    }
                }
                if (flag)
                {
                    spellTarget.Add(spellTarget);
                }
                if (!flag && (effectCategories & SpellCategory.Damages) > SpellCategory.None && spellTarget.MinDamage > (double)target.LifePoints)
                {
                    double num3 = System.Math.Max((double)target.MaxLifePoints / 2.0, (double)target.LifePoints) / spellTarget.MinDamage;
                    spellTarget.Multiply(num3);
                }
                if (spellImpact != null)
                {
                    spellImpact.Add(spellTarget);
                }
                else
                {
                    spellImpact = spellTarget;
                }
            }
        }
Пример #8
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);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #9
0
 public void AnalysePossibilities()
 {
     this.Possibilities = new System.Collections.Generic.List <SpellCastInformations>();
     foreach (Spell current in this.Fighter.Spells.Values)
     {
         SpellCategory         spellCategories       = SpellIdentifier.GetSpellCategories(current);
         SpellLevelTemplate    currentSpellLevel     = current.CurrentSpellLevel;
         SpellCastInformations spellCastInformations = new SpellCastInformations(current);
         if ((long)this.Fighter.AP >= (long)((ulong)currentSpellLevel.ApCost) && !currentSpellLevel.StatesForbidden.Any(new Func <int, bool>(this.Fighter.HasState)))
         {
             if (!currentSpellLevel.StatesRequired.Any((int state) => !this.Fighter.HasState(state)) && this.Fighter.SpellHistory.CanCastSpell(current.CurrentSpellLevel))
             {
                 if ((spellCategories & SpellCategory.Summoning) != SpellCategory.None && this.Fighter.CanSummon())
                 {
                     Cell freeAdjacentCell = this.m_environment.GetFreeAdjacentCell();
                     if (freeAdjacentCell == null)
                     {
                         continue;
                     }
                     spellCastInformations.IsSummoningSpell = true;
                     spellCastInformations.SummonCell       = freeAdjacentCell;
                 }
                 else
                 {
                     foreach (FightActor current2 in
                              from fighter in this.Fighter.Fight.Fighters
                              where fighter.IsAlive() && fighter.IsVisibleFor(this.Fighter)
                              select fighter)
                     {
                         int mPToUse;
                         if (this.CanReach(current2, current, out mPToUse) && this.Fighter.SpellHistory.CanCastSpell(current.CurrentSpellLevel, current2.Cell))
                         {
                             spellCastInformations.MPToUse = mPToUse;
                             SpellTarget spellTarget = this.ComputeSpellImpact(current, current2);
                             if (spellTarget != null)
                             {
                                 spellTarget.Target = current2;
                                 if (spellTarget.Damage >= 0.0)
                                 {
                                     spellCastInformations.Impacts.Add(spellTarget);
                                 }
                             }
                         }
                     }
                 }
                 this.Possibilities.Add(spellCastInformations);
             }
         }
     }
     if (Brain.Brain.DebugMode)
     {
         Debug.WriteLine(this.Fighter.Name);
         using (System.Collections.Generic.Dictionary <int, Spell> .ValueCollection.Enumerator enumerator = this.Fighter.Spells.Values.GetEnumerator())
         {
             while (enumerator.MoveNext())
             {
                 Spell spell = enumerator.Current;
                 Debug.WriteLine("Spell {0} ({1}) :: {2}", new object[]
                 {
                     spell.Template.Name,
                     spell.Id,
                     SpellIdentifier.GetSpellCategories(spell)
                 });
                 System.Collections.Generic.IEnumerable <SpellCastInformations> arg_2C4_0 = this.Possibilities;
                 Func <SpellCastInformations, bool> predicate = (SpellCastInformations x) => x.Spell == spell;
                 SpellCastInformations spellCastInformations2 = arg_2C4_0.FirstOrDefault(predicate);
                 if (spellCastInformations2 != null)
                 {
                     if (spellCastInformations2.IsSummoningSpell)
                     {
                         Debug.WriteLine("\tSummon Spell");
                     }
                     else
                     {
                         ObjectDumper objectDumper = new ObjectDumper(8);
                         objectDumper.MemberPredicate = ((System.Reflection.MemberInfo member) => !member.Name.Contains("Target"));
                         ObjectDumper objectDumper2 = objectDumper;
                         Debug.WriteLine("\t{0} Targets", new object[]
                         {
                             spellCastInformations2.Impacts.Count
                         });
                         foreach (SpellTarget spellTarget in spellCastInformations2.Impacts)
                         {
                             Debug.Write(objectDumper2.DumpElement(spellTarget));
                             if (spellTarget.Target != null)
                             {
                                 Debug.WriteLine("\t\tTarget = " + spellTarget.Target + spellTarget.Target.Id.ToString());
                             }
                         }
                     }
                 }
             }
         }
         Debug.WriteLine("");
     }
 }