public static Composite CreateDiscHealOnlyBehavior() { if (SingularRoutine.CurrentWoWContext == WoWContext.Normal) { return(new ActionAlwaysFail()); } HealerManager.NeedHealTargeting = true; PrioritizedBehaviorList behavs = new PrioritizedBehaviorList(); int cancelHeal = (int)Math.Max(SingularSettings.Instance.IgnoreHealTargetsAboveHealth, PriestSettings.DiscHeal.Heal); cancelHeal = (int)Math.Max(cancelHeal, PriestSettings.DiscHeal.FlashHeal); 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 behavs.AddBehavior(HealthToPriority(PriestSettings.DiscHeal.PainSuppression) + PriEmergencyBase, "Pain Suppression @ " + PriestSettings.DiscHeal.PainSuppression + "%", "Pain Suppression", new Decorator( req => Me.Combat, Spell.Cast("Pain Suppression", mov => false, on => (WoWUnit)on, req => ((WoWUnit)req).IsPlayer && ((WoWUnit)req).HealthPercent < PriestSettings.DiscHeal.PainSuppression ) ) ); behavs.AddBehavior(HealthToPriority(PriestSettings.DiscHeal.PowerWordBarrier) + PriEmergencyBase, "Power Word: Barrier @ " + PriestSettings.DiscHeal.PowerWordBarrier + "%", "Power Word: Barrier", new Decorator( ret => Me.Combat && (StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid), new PrioritySelector( context => GetBestPowerWordBarrierTarget(), new Decorator( ret => ret != null, new PrioritySelector( new Sequence( new Action(r => Logger.WriteDebug("PW:B - attempting cast")), Spell.CastOnGround("Power Word: Barrier", on => (WoWUnit)on, req => true, false) ), new Action(ret => { if (ret != null) { if (!((WoWUnit)ret).IsValid) { Logger.WriteDebug("PW:B - FAILED - Healing Target object became invalid"); } else if (((WoWUnit)ret).Distance > 40) { Logger.WriteDebug("PW:B - FAILED - Healing Target moved out of range"); } else if (!Spell.CanCastHack("Power Word: Barrier")) { Logger.WriteDebug("PW:B - FAILED - Spell.CanCastHack() said NO to Power Word: Barrier"); } else if (GameWorld.IsInLineOfSpellSight(StyxWoW.Me.GetTraceLinePos(), ((WoWUnit)ret).Location)) { Logger.WriteDebug("PW:B - FAILED - Spell.CanCastHack() unit location not in Line of Sight"); } else if (Spell.IsSpellOnCooldown("Power Word: Barrier")) { Logger.WriteDebug("PW:B - FAILED - Power Word: Barrier is on cooldown"); } else { Logger.WriteDebug("PW:B - Something FAILED with Power Word: Barrier cast sequence (target={0}, h={1:F1}%, d={2:F1} yds, spellmax={3:F1} yds, cooldown={4})", ((WoWUnit)ret).SafeName(), ((WoWUnit)ret).HealthPercent, ((WoWUnit)ret).Distance, Spell.ActualMaxRange("Power Word: Barrier", (WoWUnit)ret), Spell.IsSpellOnCooldown("Power Word: Barrier") ); } } return(RunStatus.Failure); }) ) ) ) ) ); #endregion #region Tank Buffing behavs.AddBehavior(HealthToPriority(99) + PriHighBase, "Power Word: Shield - Tank", "Power Word: Shield", new Decorator( req => Me.Combat, Spell.Buff( "Power Word: Shield", on => Group.Tanks .FirstOrDefault(u => u.IsAlive && CanWePwsUnit(u) && Spell.CanCastHack("Power Word: Shield", u)) ) ) ); behavs.AddBehavior(HealthToPriority(99) + PriHighBase, "Plea - Tank Attonement", "Plea", new Decorator( req => Me.Combat, Spell.Cast( "Plea", on => Group.Tanks .FirstOrDefault(u => u.IsAlive && !u.HasActiveAura("Atonement") && Spell.CanCastHack("Plea", u)) ) ) ); #endregion #region Save the Highest Priority Targets const int SaveEssential = 30; behavs.AddBehavior(HealthToPriority(SaveEssential) + PriSaveEssential, "Save Highest Priority Target below " + SaveEssential + "%", "Shadow Mend", new Decorator( req => Me.Combat, new PrioritySelector( ctx => HealerManager.FindHighestPriorityTarget(), Spell.HandleOffGCD(Spell.Buff("Power Infusion", on => Me, req => req != null, gcd: HasGcd.No)), Spell.Buff( "Power Word: Shield", on => (WoWUnit)on, req => ((WoWUnit)req).HealthPercent < PriestSettings.DiscHeal.PowerWordShield && CanWePwsUnit((WoWUnit)req) ), Spell.Cast( "Plea", on => (WoWUnit)on, req => !((WoWUnit)req).HasActiveAura("Atonement") ), Spell.Cast( "Shadow Mend", on => (WoWUnit)on, req => ((WoWUnit)req).HealthPercent < PriestSettings.DiscHeal.ShadowMend ) ) ) ); #endregion #region AoE Heals if (PriestSettings.DiscHeal.DiscLevel90Talent != 0) { behavs.AddBehavior(HealthToPriority(PriestSettings.DiscHeal.DiscLevel90Talent) + PriAoeBase, "Halo @ " + PriestSettings.DiscHeal.DiscLevel90Talent + "% MinCount: " + PriestSettings.DiscHeal.CountLevel90Talent, "Halo", new Decorator( ret => SingularRoutine.CurrentWoWContext == WoWContext.Battlegrounds || SingularRoutine.CurrentWoWContext == WoWContext.Instances, new Decorator( ret => ret != null && HealerManager.Instance.TargetList.Count(u => u.IsAlive && u.HealthPercent < PriestSettings.DiscHeal.DiscLevel90Talent && u.Distance < 30) >= PriestSettings.DiscHeal.CountLevel90Talent && Spell.CanCastHack("Halo", (WoWUnit)ret), new PrioritySelector( Spell.HandleOffGCD(Spell.BuffSelf("Archangel", req => ((WoWUnit)req) != null && Me.HasAura("Evangelism", 5))), Spell.CastOnGround("Halo", on => (WoWUnit)on, req => true) ) ) ) ); } if (PriestSettings.DiscHeal.DiscLevel90Talent != 0) { behavs.AddBehavior(HealthToPriority(PriestSettings.DiscHeal.DiscLevel90Talent) + PriAoeBase, "Cascade @ " + PriestSettings.DiscHeal.DiscLevel90Talent + "% MinCount: " + PriestSettings.DiscHeal.CountLevel90Talent, "Cascade", new Decorator( ret => StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid, new PrioritySelector( context => HealerManager.GetBestCoverageTarget("Cascade", PriestSettings.DiscHeal.DiscLevel90Talent, 40, 30, PriestSettings.DiscHeal.CountLevel90Talent), new Decorator( ret => ret != null && Spell.CanCastHack("Cascade", (WoWUnit)ret), new PrioritySelector( Spell.HandleOffGCD(Spell.BuffSelf("Archangel", req => Me.HasAura("Evangelism", 5))), Spell.Cast("Cascade", mov => true, on => (WoWUnit)on, req => true) ) ) ) ) ); } if (PriestSettings.DiscHeal.PowerWordRadiance != 0) { behavs.AddBehavior(99 + PriAoeBase, "Power Word: Radiance", "Power Word: Radiance", new Decorator( ret => StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid, new PrioritySelector( context => HealerManager.GetBestCoverageTarget("Power Word: Radiance", PriestSettings.DiscHeal.PowerWordRadiance, 40, 30, PriestSettings.DiscHeal.CountPowerWordRadiance, o => o != null && !((WoWUnit)o).HasActiveAura("Atonement")), CastBuffsBehavior("Power Word: Radiance"), Spell.Cast("Power Word: Radiance", on => (WoWUnit)on) ) ) ); } #endregion #region Direct Heals if (PriestSettings.DiscHeal.Plea != 0) { behavs.AddBehavior(100 + PriSingleBase, "Atonement Plea @ " + PriestSettings.DiscHeal.Plea + "%", "Plea", new Decorator( req => !((WoWUnit)req).HasActiveAura("Atonement"), new PrioritySelector( CastBuffsBehavior("Plea"), Spell.Cast("Plea", mov => false, on => (WoWUnit)on, req => true, cancel => false ) ) ) ); } if (HasReflectiveShield) { behavs.AddBehavior(100 + PriSingleBase, "Power Word: Shield Self (Glyph of Reflective Shield)", "Power Word: Shield", Spell.BuffSelf("Power Word: Shield", req => CanWePwsUnit(Me) && Unit.NearbyUnitsInCombatWithUsOrOurStuff.Any()) ); } if (PriestSettings.DiscHeal.PowerWordShield != 0) { behavs.AddBehavior(99 + PriSingleBase, "Power Word: Shield @ " + PriestSettings.DiscHeal.PowerWordShield + "%", "Power Word: Shield", Spell.Buff("Power Word: Shield", on => (WoWUnit)on, req => ((WoWUnit)req).HealthPercent < PriestSettings.DiscHeal.PowerWordShield && CanWePwsUnit((WoWUnit)req)) ); } #endregion behavs.OrderBehaviors(); behavs.ListBehaviors(); return(new PrioritySelector( ctx => HealerManager.FindHighestPriorityTarget(), Spell.WaitForCastOrChannel(), new Decorator( ret => !Spell.IsGlobalCooldown() && ret != null, behavs.GenerateBehaviorTree() ) )); }