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()); }
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); } } } } } } } } } }