예제 #1
0
        //private static WoWUnit _moveToHealTarget = null;
        //private static WoWUnit _lastMoveToTarget = null;

        public static Composite CreateHolyHealOnlyBehavior(bool selfOnly, bool moveInRange)
        {
            if (SingularRoutine.CurrentWoWContext == WoWContext.Normal)
            {
                return(new ActionAlwaysFail());
            }

            HealerManager.NeedHealTargeting = true;
            PrioritizedBehaviorList behavs = new PrioritizedBehaviorList();
            int cancelHeal = Math.Max(SingularSettings.Instance.IgnoreHealTargetsAboveHealth, Math.Max(PriestSettings.HolyHeal.Heal, PriestSettings.HolyHeal.Renew));

            Logger.WriteDebugInBehaviorCreate("Priest Healing: will cancel cast of direct heal if health reaches {0:F1}%", cancelHeal);

            if (SingularSettings.Instance.DispelDebuffs != RelativePriority.None)
            {
                int dispelPriority = (SingularSettings.Instance.DispelDebuffs == RelativePriority.HighPriority) ? 999 : -999;
                behavs.AddBehavior(dispelPriority, "Dispel", null, Common.CreatePriestDispelBehavior());
            }

            #region Save the Group

            if (PriestSettings.HolyHeal.DivineHymn != 0)
            {
                behavs.AddBehavior(HealthToPriority(PriestSettings.HolyHeal.DivineHymn) + 300, "Divine Hymn @ " + PriestSettings.HolyHeal.DivineHymn + "% MinCount: " + PriestSettings.HolyHeal.CountDivineHymn, "Divine Hymn",
                                   new Decorator(
                                       ret => StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid,
                                       new PrioritySelector(
                                           context => HealerManager.GetBestCoverageTarget("Divine Hymn", PriestSettings.HolyHeal.DivineHymn, 0, 40, PriestSettings.HolyHeal.CountDivineHymn),
                                           new Decorator(
                                               ret => ret != null,
                                               Spell.Cast("Divine Hymn", mov => false, on => (WoWUnit)on, req => true, cancel => false)
                                               )
                                           )
                                       )
                                   );
            }

            if (PriestSettings.HolyHeal.GuardianSpirit != 0)
            {
                behavs.AddBehavior(HealthToPriority(PriestSettings.HolyHeal.GuardianSpirit) + 300, "Guardian Spirit @ " + PriestSettings.HolyHeal.GuardianSpirit + "%", "Guardian Spirit",
                                   Spell.Cast("Guardian Spirit",
                                              mov => false,
                                              on => (WoWUnit)on,
                                              req => ((WoWUnit)req).HealthPercent < PriestSettings.HolyHeal.GuardianSpirit
                                              )
                                   );
            }

            if (PriestSettings.LightOfTuure != 0)
            {
                behavs.AddBehavior(HealthToPriority(PriestSettings.LightOfTuure) + 300, "Light of T'uure @ " + PriestSettings.LightOfTuure + "%", "Light of T'uure",
                                   Spell.Cast("Light of T'uure",
                                              mov => false,
                                              on => (WoWUnit)on,
                                              req => ((WoWUnit)req).HealthPercent < PriestSettings.LightOfTuure && !((WoWUnit)req).HasAura("Light of T'uure") &&
                                              Group.Tanks.Contains(((WoWUnit)req))
                                              )
                                   );
            }

            #endregion

            #region AoE Heals

            int maxDirectHeal = Math.Max(PriestSettings.HolyHeal.FlashHeal, PriestSettings.HolyHeal.Heal);

            // instant, so cast this first ALWAYS
            if (PriestSettings.HolyHeal.HolyWordSanctify != 0)
            {
                behavs.AddBehavior(398, "Holy Word: Sanctify @ " + PriestSettings.HolyHeal.HolyWordSanctify + "% MinCount: " + PriestSettings.HolyHeal.CountHolyWordSanctify, "Holy Word: Sanctify",
                                   new Decorator(
                                       ret => true,
                                       new PrioritySelector(
                                           context => HealerManager.GetBestCoverageTarget("Holy Word: Sanctify", PriestSettings.HolyHeal.HolyWordSanctify, 40, 10, PriestSettings.HolyHeal.CountHolyWordSanctify),
                                           new Decorator(
                                               ret => ret != null,
                                               Spell.CastOnGround("Holy Word: Sanctify", on => (WoWUnit)on, req => true, false)
                                               )
                                           )
                                       )
                                   );
            }

            if (PriestSettings.HolyHeal.PrayerOfMending != 0)
            {
                behavs.AddBehavior(397, "Prayer of Mending @ " + PriestSettings.HolyHeal.PrayerOfMending + "%", "Prayer of Mending",
                                   Spell.Cast("Prayer of Mending",
                                              mov => true,
                                              on => (WoWUnit)on,
                                              req => !((WoWUnit)req).IsMe && ((WoWUnit)req).HealthPercent <PriestSettings.HolyHeal.PrayerOfMending,
                                                                                                           cancel => ((WoWUnit)cancel).HealthPercent> cancelHeal
                                              )
                                   );
            }

/*
 *          behavs.AddBehavior(HealthToPriority(PriestSettings.HolyHeal.HolyLevel90Talent) + 200, "Divine Star",
 *              "Divine Star",
 *              new Decorator(
 *                  ret => StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid,
 *                  new Decorator(
 *                      ret =>
 *                          Clusters.GetClusterCount(Me,
 *                              HealerManager.Instance.TargetList.Where(
 *                                  u => u.HealthPercent < PriestSettings.HolyHeal.CountLevel90Talent).ToList(),
 *                              ClusterType.PathToUnit, 4) >= PriestSettings.HolyHeal.CountLevel90Talent,
 *                      Spell.Cast("Divine Star", on => (WoWUnit)on, req => true)
 *                      )
 *                  )
 *              );
 */

            if (PriestSettings.HolyHeal.HolyLevel90Talent != 0)
            {
                behavs.AddBehavior(397,
                                   "Halo @ " + PriestSettings.HolyHeal.HolyLevel90Talent + "% MinCount: " +
                                   PriestSettings.HolyHeal.CountLevel90Talent, "Halo",
                                   new Decorator(
                                       ret => StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid,
                                       new Decorator(
                                           ret => ret != null
                                           &&
                                           HealerManager.Instance.TargetList.Count(
                                               u =>
                                               u.IsAlive && u.HealthPercent < PriestSettings.HolyHeal.HolyLevel90Talent &&
                                               u.Distance < 30) >= PriestSettings.HolyHeal.CountLevel90Talent && Unit.UnfriendlyUnits(30).Any(u => u.Combat && !u.IsCrowdControlled()),
                                           Spell.Cast("Halo", req => true)
                                           )
                                       )
                                   );
            }

            if (PriestSettings.HolyHeal.BindingHeal != 0)
            {
                behavs.AddBehavior(396, "Binding Heal @ " + PriestSettings.HolyHeal.BindingHeal + "% MinCount: 2", "Binding Heal",
                                   Spell.Cast("Binding Heal",
                                              mov => true,
                                              on => (WoWUnit)on,
                                              req => !((WoWUnit)req).IsMe && ((WoWUnit)req).HealthPercent < PriestSettings.HolyHeal.BindingHeal && Me.HealthPercent <PriestSettings.HolyHeal.BindingHeal,
                                                                                                                                                                     cancel => ((WoWUnit)cancel).HealthPercent> cancelHeal
                                              )
                                   );
            }

            if (PriestSettings.HolyHeal.CircleOfHealing != 0)
            {
                behavs.AddBehavior(395, "Circle of Healing @ " + PriestSettings.HolyHeal.CircleOfHealing + "% MinCount: " + PriestSettings.HolyHeal.CountCircleOfHealing, "Circle of Healing",
                                   new Decorator(
                                       ret => StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid,
                                       new PrioritySelector(
                                           context => HealerManager.GetBestCoverageTarget("Circle of Healing", PriestSettings.HolyHeal.CircleOfHealing, 40, 30, PriestSettings.HolyHeal.CountCircleOfHealing),
                                           Spell.Cast("Circle of Healing", on => (WoWUnit)on)
                                           )
                                       )
                                   );
            }

            if (PriestSettings.HolyHeal.PrayerOfHealing != 0)
            {
                behavs.AddBehavior(394, "Prayer of Healing @ " + PriestSettings.HolyHeal.PrayerOfHealing + "% MinCount: " + PriestSettings.HolyHeal.CountPrayerOfHealing, "Prayer of Healing",
                                   new Decorator(
                                       ret => StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid,
                                       new PrioritySelector(
                                           context => HealerManager.GetBestCoverageTarget("Prayer of Healing", PriestSettings.HolyHeal.PrayerOfHealing, 40, 20, PriestSettings.HolyHeal.CountPrayerOfHealing),
                                           Spell.Cast("Prayer of Healing", on => (WoWUnit)on)
                                           )
                                       )
                                   );
            }

            #endregion

            /*
             * HolyWordSanctify       Holy Word: Sanctify
             * HolyWordSerenity        Holy Word: Serenity
             * CircleOfHealing         Circle of Healing
             * PrayerOfHealing         Prayer of Healing
             * DivineHymn              Divine Hymn
             * GuardianSpirit          Guardian Spirit
             * VoidShift               Void Shift
             */

            #region Direct Heals

            if (maxDirectHeal != 0) // Nuke a Flash Heal
            {
                behavs.AddBehavior(400, "Surge of Light @ " + maxDirectHeal + "%", "Flash Heal",
                                   Spell.Cast("Flash Heal",
                                              mov => false,
                                              on => (WoWUnit)on,
                                              req => Me.HasActiveAura("Surge of Light") && ((WoWUnit)req).HealthPercent < 85
                                              )
                                   );
            }

            if (PriestSettings.HolyHeal.HolyWordSerenity != 0)
            {
                behavs.AddBehavior(HealthToPriority(1) + 4, "Holy Word: Serenity @ " + PriestSettings.HolyHeal.HolyWordSerenity + "%", "Holy Word: Serenity",
                                   Spell.CastHack("Holy Word: Serenity",
                                                  on => (WoWUnit)on,
                                                  req => ((WoWUnit)req).HealthPercent < PriestSettings.HolyHeal.HolyWordSerenity
                                                  )
                                   );
            }

            var cmt             = "";
            var flashHealHealth = PriestSettings.HolyHeal.FlashHeal;
            if (!SpellManager.HasSpell("Heal"))
            {
                flashHealHealth = Math.Max(flashHealHealth, PriestSettings.HolyHeal.Heal);
                cmt             = "(Adjusted for Heal)";
            }

            if (flashHealHealth != 0)
            {
                behavs.AddBehavior(HealthToPriority(PriestSettings.HolyHeal.FlashHeal), "Flash Heal @ " + flashHealHealth + "% " + cmt, "Flash Heal",
                                   Spell.Cast("Flash Heal",
                                              mov => true,
                                              on => (WoWUnit)on,
                                              req => ((WoWUnit)req).HealthPercent <flashHealHealth,
                                                                                   cancel => ((WoWUnit)cancel).HealthPercent> cancelHeal
                                              )
                                   );
            }

            if (PriestSettings.HolyHeal.Heal != 0)
            {
                behavs.AddBehavior(HealthToPriority(PriestSettings.HolyHeal.Heal), "Heal @ " + PriestSettings.HolyHeal.Heal + "%", "Heal",
                                   Spell.Cast("Heal",
                                              mov => true,
                                              on => (WoWUnit)on,
                                              req => ((WoWUnit)req).HealthPercent <PriestSettings.HolyHeal.Heal,
                                                                                   cancel => ((WoWUnit)cancel).HealthPercent> cancelHeal
                                              )
                                   );
            }

            #endregion

            #region Tank - Low Priority Buffs

            if (PriestSettings.HolyHeal.Renew != 0)
            {
                behavs.AddBehavior(HealthToPriority(102), "Tank - Buff Renew @ " + PriestSettings.HolyHeal.Renew + "%", "Renew",
                                   // roll Renew on Tanks
                                   Spell.Cast("Renew", on =>
                {
                    WoWUnit unit = HealerManager.GetBestTankTargetForHOT("Renew", PriestSettings.HolyHeal.Renew);
                    if (unit != null && Spell.CanCastHack("Renew", unit, skipWowCheck: true))
                    {
                        Logger.WriteDebug("Buffing RENEW ON TANK: {0}", unit.SafeName());
                        return(unit);
                    }
                    return(null);
                })
                                   );
            }
            #endregion


            #region Lowest Priority Healer Tasks

            if (SingularRoutine.CurrentWoWContext == WoWContext.Instances)
            {
                behavs.AddBehavior(HealthToPriority(103), "Lightwell", "Lightwell",
                                   new Throttle(TimeSpan.FromSeconds(20),
                                                new Sequence(
                                                    new Action(r =>
                {
                    _lightwellTarget = Group.Tanks.FirstOrDefault(t =>
                    {
                        if (t.IsAlive && t.Combat && t.GotTarget() && t.CurrentTarget.IsBoss())
                        {
                            if (t.Distance < 40 && t.SpellDistance(t.CurrentTarget) < 15)
                            {
                                Logger.WriteDiagnostic("Lightwell: found target {0}", t.SafeName());
                                return(true);
                            }
                        }
                        return(false);
                    });

                    return(_lightwellTarget == null ? RunStatus.Failure : RunStatus.Success);
                }),
                                                    Spell.CastOnGround("Lightwell",
                                                                       location => WoWMathHelper.CalculatePointFrom(Me.Location, _lightwellTarget.Location, (float)Math.Min(10.0, _lightwellTarget.Distance / 2)),
                                                                       req => _lightwellTarget != null,
                                                                       false,
                                                                       desc => string.Format("10 yds from {0}", _lightwellTarget.SafeName())
                                                                       )
                                                    )
                                                )
                                   );
            }
            #endregion

            behavs.OrderBehaviors();

            if (selfOnly == false && CompositeBuilder.CurrentBehaviorType == BehaviorType.Combat)
            {
                behavs.ListBehaviors();
            }

            return(new PrioritySelector(
                       ctx => selfOnly ? StyxWoW.Me : HealerManager.FindLowestHealthTarget(), // HealerManager.Instance.FirstUnit,

                       Spell.WaitForCastOrChannel(),

                       new Decorator(
                           ret => !Spell.IsGlobalCooldown() && ret != null,
                           behavs.GenerateBehaviorTree()
                           ),

                       new Decorator(
                           ret => moveInRange,
                           Movement.CreateMoveToUnitBehavior(
                               ret => Battlegrounds.IsInsideBattleground ? (WoWUnit)ret : Group.Tanks.Where(a => a.IsAlive).OrderBy(a => a.Distance).FirstOrDefault(),
                               35f
                               )
                           )
                       ));
        }