All pastes #548366 Raw Edit

fichier de configuration d'un bo

public text v1 · immutable
·published 2007-06-07 18:24 UTC
rendered paste body
// Priest.cs - default Glider class file.
//
// Ma6 21 2007 MMD - Added call for combat debuff removal.
// Apr 27 2007 MMD - Created base class from old priest.
//
//////////////////////////////////////////////////////////////////////////
//
// IMPORTANT!  DO NOT MODIFY THIS FILE!  It is not read by Glider during
// usage.  To change the behavior of this class, copy this file into the
// "Classes" folder and give it a new name, then modify it.  And remove
// this warning, too.
//
// For more information on custom classes, please visit:
//
//          http://mmoglider.com/customclasses
//

using System;
using System.Threading;
using Glider.Common.Objects;

namespace Glider.Common.Objects
{
    public class Priest : GGameClass
    {
        const double MIN_FLAY_DISTANCE = 10.0;

        #region Priest properties/config
        GSpellTimer Fortitude = new GSpellTimer(27 * 60 * 1000, false);         // Assume it's not totally fresh each time.
        GSpellTimer InnerFire = new GSpellTimer(5 * 60 * 1000, true);          // Five minutes if we don't find the id...
        int InnerFireBuffID = 0;
        GSpellTimer Mindblast;  // Duration set by config.
        GSpellTimer Pain;       // Duration set by config.
        GSpellTimer Shield;     // Duration set by config.
        GSpellTimer Renew = new GSpellTimer(15 * 1000);
        GSpellTimer Potion = new GSpellTimer(2 * 60 * 1000);
        GSpellTimer FlashHeal = new GSpellTimer(10 * 1000);   // Avoid loop of spamming flash heal.
        GSpellTimer Fade = new GSpellTimer(30 * 1000);

        bool ShouldFlay;
        bool FlayRunners;
        bool ShouldWand;
        bool PreShield;
        bool AlwaysShield;
        bool SkipFlayRange;
        bool UseShadowform;
        bool UseVampiric;
        bool ExtraFlay;

        #endregion

        #region GGameClass overrides
        public override string DisplayName
        {
            get { return "Priest"; }
        }

        public override GConfigResult ShowConfiguration()
        {
            return Context.ShowStockConfigDialog(GPlayerClass.Priest);
        }

        public override void CreateDefaultConfig()
        {
            Context.SetConfigValue("Priest.ShadowWordCooldown", "18", false);
            Context.SetConfigValue("Priest.MindblastCooldown", "8", false);
            Context.SetConfigValue("Priest.MindFlay", "True", false);
            Context.SetConfigValue("Priest.UseWand", "True", false);
            Context.SetConfigValue("Priest.PullDistance", "30", false);
            Context.SetConfigValue("Priest.ShieldCooldown", "15", false);
            Context.SetConfigValue("Priest.PreShield", "True", false);
            Context.SetConfigValue("Priest.AlwaysShield", "False", false);
            Context.SetConfigValue("Priest.SkipFlayRange", "False", false);
            Context.SetConfigValue("Priest.FlayRunners", "True", false);
            Context.SetConfigValue("Priest.UseShadowform", "False", false);
            Context.SetConfigValue("Priest.UseVampiric", "False", false);
            Context.SetConfigValue("Priest.ExtraFlay", "False", false);
        }

        public override void LoadConfig()
        {
            Pain = new GSpellTimer(Context.GetConfigInt("Priest.ShadowWordCooldown") * 1000, true);
            Mindblast = new GSpellTimer(Context.GetConfigInt("Priest.MindblastCooldown") * 1000, true);
            Shield = new GSpellTimer(Context.GetConfigInt("Priest.ShieldCooldown") * 1000, true);
            ShouldFlay = Context.GetConfigBool("Priest.MindFlay");
            ShouldWand = Context.GetConfigBool("Priest.UseWand");
            PreShield = Context.GetConfigBool("Priest.PreShield");
            AlwaysShield = Context.GetConfigBool("Priest.AlwaysShield");
            SkipFlayRange = Context.GetConfigBool("Priest.SkipFlayRange");
            FlayRunners = Context.GetConfigBool("Priest.FlayRunners");
            UseShadowform = Context.GetConfigBool("Priest.UseShadowform");
            UseVampiric = Context.GetConfigBool("Priest.UseVampiric");
            ExtraFlay = Context.GetConfigBool("Priest.ExtraFlay");
        }

        public override void ResetBuffs()
        {
            Context.Log("Priest.ResetBuffs invoked, clearing out buffs");
            InnerFire.ForceReady();
            Fortitude.ForceReady();
        }

        public override bool Rest()
        {
            // Check to see if we should cast a heal spell here:

            if (!IsShadowform)
            {
                if (Me.Health < .6)
                    Context.CastSpell("Priest.RestHeal");
                else
                {
                    if (Me.Health < .8 && Renew.IsReady)
                    {
                        Context.CastSpell("Priest.Renew");
                        Renew.Reset();
                    }
                }
            }
            else
            {
                if (Me.Health < Context.RestHealth)
                {
                    Context.CastSpell("Priest.Shadowform");

                    if (Me.Health < .4)
                        Context.CastSpell("Priest.RestHeal");
                    else
                        Context.CastSpell("Priest.FlashHeal");

                    Thread.Sleep(1777);

                    if (Me.Health < .85 && Renew.IsReady)
                    {
                        Context.CastSpell("Priest.Renew");
                        Renew.Reset();
                    }
                }
            }

            if (InnerFireBuffID == 0)
            {
                // We don't know the buffid, try to guess it.
                Context.Log("Guessing inner fire buffid");
                Context.CastSpell("Priest.InnerFire");
                GSpellTimer Futile = new GSpellTimer(5000, false);

                while (!Futile.IsReadySlow)
                {
                    InnerFireBuffID = FindInnerFire();

                    if (InnerFireBuffID != 0)
                        break;
                }

                if (InnerFireBuffID == 0)  // Never found it.
                {
                    Context.Log("Never found inner fire buff, going with timer");
                    InnerFireBuffID = -1;
                }
                else
                    Context.Log("Inner fire buffid = 0x" + InnerFireBuffID.ToString("x"));
            }

            return base.Rest();
        }

        public override void RunningAction()
        {
            Context.Debug("Priest.RunningAction invoked");

            if (Context.RemoveDebuffs(GBuffType.Disease, "Priest.CureDisease", false) ||
                Context.RemoveDebuffs(GBuffType.Magic, "Priest.Dispel", false))
                return;

            // Got Inner Fire buffid but it's gone?  Recast.
            if (InnerFireBuffID > 0 && !Me.HasBuff(InnerFireBuffID))
            {
                Context.CastSpell("Priest.InnerFire");
                return;
            }

            // No buffid?  Check timer.
            if (InnerFireBuffID <= 0 && InnerFire.IsReady)
            {
                InnerFire.Reset();
                Context.CastSpell("Priest.InnerFire");
                return;
            }

            // Only cast fort if we have a ton of mana.
            Context.Debug("Fortitude.IsReady = " + Fortitude.IsReady + ", Me.Mana = " + Me.Mana);

            if (Fortitude.IsReady && Me.Mana > .4)   
            {
                Context.CastSpell("Priest.PWFort");
                Fortitude.Reset();
                return;
            }

            // Pop into shadowform.
            if (UseShadowform && !IsShadowform && Me.Mana > .40)  
            {
                Context.CastSpell("Priest.Shadowform");
                return;
            }
        }

        public override void ApproachingTarget(GUnit Target)
        {
            if (PreShield)
            {
                Shield.Reset();
                Context.CastSpell("Priest.Shield");
            }
        }

        public override GCombatResult KillTarget(GUnit Target, bool IsAmbush)
        {
            GSpellTimer CombatCheck = new GSpellTimer(3000, false);
            Context.Debug("Priest.KillTarget invoked, isAmbush = " + IsAmbush + ", Target = " + Target.ToString() + ", distance = " + Target.DistanceToSelf);
            Context.ReleaseSpinRun();  // No charging in going on here.

            if (Target.IsPlayer)
                return KillPlayer((GPlayer)Target, GPlayerSelf.Me.Location);

            GMonster Monster = (GMonster)Target;

            Target.Face();

            if (!IsHealer)
            {
                if (AlwaysShield || PreShield)
             
                    {
                        Shield.Reset();
                        Context.CastSpell("Priest.Shield");

                        if (Target.DistanceToSelf > PullDistance)
                            Target.Approach(PullDistance, false);
                    
                }

                Mindblast.Reset();
                Context.CastSpell("Priest.MindBlast");612

                if (UseVampiric && Me.Health < .85)
                {
                    if (Target.DistanceToSelf <= PullDistance)
                        Context.CastSpell("Priest.Vampiric");
                }

                if (ShouldFlay && Target.DistanceToSelf >= MIN_FLAY_DISTANCE)
                {
                    if (Target.DistanceToSelf > FlayPull && !SkipFlayRange)
                        Target.WaitForApproach(FlayPull, 3000);

                    if (Target.DistanceToSelf <= FlayPull)
                        Context.CastSpell("Priest.MindFlay");
                }

                GCombatResult PullCheck = Context.WaitForEngage(Monster, this.PullDistance);
                if (PullCheck != GCombatResult.Unknown)
                    return PullCheck;

                Pain.Reset();
                Context.CastSpell("Priest.SWPain");
            }

            if (!IsHealer && Target.IsTargetingMe && PreShield && Shield.IsReady)
            {
                Shield.Reset();
                Context.CastSpell("Priest.Shield");
            }

            // Before anything, see if we should throw on a quick renew:
            if (Me.Health < .8 && Renew.IsReady && !IsShadowform)
            {
                Context.CastSpell("Priest.Renew");
                Renew.Reset();
            }

            if (ShouldWand || IsHealer)
                Target.Approach(30.0, false);  // Wand range.

            if (ExtraFlay && Shield.TicksLeft > 5000 && Target.DistanceToSelf < FlayPull && !IsHealer)
                Context.CastSpell("Priest.MindFlay");

            if (IsShadowform)
                CheckHealthStuffShadowform(Target);
            else
                CheckHealthStuff(Target);

            bool IsClose = false;

            while (true)
            {
                Thread.Sleep(101);

                GCombatResult CommonResult = Context.CheckCommonCombatResult(Monster, IsAmbush);

                if (CommonResult != GCombatResult.Unknown)
                    return CommonResult;

                if (ShouldWand && (Target.Health < .8 || !IsHealer))
                    StartWand();

                Target.Face();

                double Distance = Target.DistanceToSelf;

                if (Distance <= Context.MeleeDistance)
                    IsClose = true;

                if (Distance > Context.MeleeDistance && IsClose && FlayRunners)
                {
                    IsClose = false;
                    StopWand();
                    Context.CastSpell("Priest.MindFlay");
                    continue;
                }

                if (CheckPartyHeal(Target))
                    continue;

                if (IsHealer)
                {
                    if (Target.Health < .90 && Target.Health > .10 && Pain.IsReady && !Interface.IsKeyFiring("Priest.Wand"))
                    {
                        Context.CastSpell("Priest.SWPain");
                        Pain.Reset();
                    }

                    if (Target.DistanceToSelf <= Context.MeleeDistance && !Me.IsMeleeing)
                        Context.CastSpell("Common.ToggleCombat", false, true);

                    CheckHealthStuff(Target);

                    if (Target.IsTargetingMe && IsHealer && Fade.IsReady)  // Monster is targeting me.  Damn.
                    {
                        Context.CastSpell("Priest.Fade");
                        Fade.Reset();
                    }

                    if (Me.Health < .85 && Renew.IsReady)
                    {
                        Context.CastSpell("Priest.Renew");
                        Renew.Reset();
                        continue;
                    }

                    if (Me.Health < .60)
                    {
                        Context.CastSpell("Priest.FlashHeal");
                        continue;
                    }

                    continue;
                }

                // Ok, combat moves:
Shield.Reset();
                if (Mindblast.IsReady && Mindblast.Duration > 0)
                {
                    StopWand();

                    if (AlwaysShield && Shield.IsReady && Target.Health > .20)
                    {
                        Shield.Reset();
                        Context.CastSpell("Priest.Shield");
                    }

                    Context.CastSpell("Priest.MindBlast");
                    Mindblast.Reset();
                }

                // Maybe SW:P wore off?  Probably not good if it's taking this long...
                if (Pain.IsReady && Target.Health > .35)
                {
                    StopWand();

                    Pain.Reset();
                    Context.CastSpell("Priest.SWPain");
                }

                if (Target.DistanceToSelf <= Context.MeleeDistance && !Me.IsMeleeing && !ShouldWand)
                    Context.CastSpell("Common.ToggleCombat", false, true);

                // Put IF back up if we know the id and we're not wanding.
                if (InnerFireBuffID > 0 && !Me.HasBuff(InnerFireBuffID) && !Interface.IsKeyFiring("Priest.Wand"))
                    Context.CastSpell("Priest.InnerFire");

                if (Context.RemoveDebuffs(GBuffType.Disease, "Priest.CureDisease", true) ||
                    Context.RemoveDebuffs(GBuffType.Magic, "Priest.Dispel", true))
                    continue;

                if (IsShadowform)
                    CheckHealthStuffShadowform(Target);
                else
                    CheckHealthStuff(Target);
            }
        }
        #endregion

        #region Priest helpers
        bool IsShadowform
        {
            get
            {
                return Me.HasWellKnownBuff("Shadowform");
            }
        }

        int FindInnerFire()
        {
            GBuff[] Buffs = Me.GetBuffSnapshot();

            foreach (GBuff one in Buffs)
                if (one.ChargesLeft == 20)  // Looks like a fresh inner fire to me.
                    return one.SpellID;

            return 0;   // Never found it.
        }

        public bool CheckHealthStuffShadowform(GUnit Target)
        {
            if (AlwaysShield && Shield.IsReady && Target.Health > .25)
            {
                StopWand();
                Shield.Reset();
                Context.CastSpell("Priest.Shield");
                return true;
            }

            if ((Me.Health < .5 && Target.Health > .40) ||
                (Me.Health < .25))
            {
                if (Shield.IsReady)
                {
                    Shield.Reset();
                    Context.CastSpell("Priest.Shield");
                }

                Context.CastSpell("Priest.Shadowform");

                if (Me.Health < .2 && Potion.IsReady)
                {
                    Context.CastSpell("Common.Potion");
                    Potion.Reset();
                }

                if (Me.Health < .4)
                    Context.CastSpell("Priest.RestHeal");
                else
                    Context.CastSpell("Priest.FlashHeal");

                if (Me.Health < .85 && Renew.IsReady)
                {
                    Context.CastSpell("Priest.Renew");       // Throw this on.
                    Renew.Reset();
                }

                if (Me.Mana >= .50)
                    Context.CastSpell("Priest.Shadowform");

                return true;
            }

            return false;
        }

        public bool CheckHealthStuff(GUnit Target)
        {
            if (AlwaysShield && Shield.IsReady && Target.Health > .15)
            {
                StopWand();
                Shield.Reset();
                Context.CastSpell("Priest.Shield");
                return true;
            }

            // Check for mini-heal:
            if (Me.Health < .7 && Me.Health > .5 && FlashHeal.IsReady && Target.Health > .20)
            {

                FlashHeal.Reset();
                StopWand();
                if (Shield.IsReady)
                {
                    Shield.Reset();
                    Context.CastSpell("Priest.Shield");
                }

                Context.CastSpell("Priest.FlashHeal");
                return true;
            }

            // Check for big-time heal next:
            if ((Me.Health < .6 && Target.Health > .20) ||
                Me.Health < .4)
            {
                if (Shield.IsReady || AlwaysShield)   // Do the big heal.
                {
                    StopWand();
                    if (!AlwaysShield)
                    {
                        Shield.Reset();
                        Context.CastSpell("Priest.Shield");
                    }

                    Context.CastSpell("Priest.RestHeal");
                    return true;
                }

                // No shield, do flash heal.

                if (Me.Mana > .08)
                {
                    StopWand();
                    Context.CastSpell("Priest.FlashHeal");
                    return true;
                }

                // If we got here, bad shit must be happening.
                if (Potion.IsReady)
                {
                    StopWand();
                    Potion.Reset();
                    Context.CastSpell("Common.Potion");
                    return true;
                }
            }

            // Check for light heal first:
            double RenewPct = .8;

            if (Context.Interface.IsKeyFiring("Priest.Wand"))   // Don't break out so easily if we're wanding.
                RenewPct = .6;

            if (Me.Health < RenewPct && Target.Health > .35)
            {
                if (Renew.IsReady)
                {
                    StopWand();
                    Context.CastSpell("Priest.Renew");
                    Renew.Reset();
                    return true;
                }
            }

            return false;
        }


        void StopWand()
        {
            if (!Context.Interface.IsKeyFiring("Priest.Wand"))  // Not firing, screw it.
                return;

            Context.CastSpell("Priest.Wand", false, false);
        }

        void StartWand()
        {
            if (ShouldWand && !Context.Interface.IsKeyFiring("Priest.Wand"))
                Context.CastSpell("Priest.Wand");
        }

        bool IsHealer
        {
            get
            {
                return Context.Party.HealMode == GHealDisposition.Dedicated;
            }
        }


        #endregion

        #region Party stuff
        public override bool CheckPartyHeal(GUnit OriginalTarget)
        {
            bool Healed = false;

            if (Context.Party.HealMode == GHealDisposition.Never ||
                Context.Party.Mode == GPartyMode.Solo)  // Don't think so.
                return false;

            foreach (GPlayer Guy in Context.Party.GetPartyMemberObjects())
            {
                double HotCheck = .80;
                double HealCheck = .55;
                double ShieldCheck = .25;

                if (IsHealer)         // Faster healing.
                    HealCheck = .65;

                if (OriginalTarget != null && OriginalTarget.IsTargetingMe)  // If it's hitting me, lower threshold...
                {
                    HealCheck = .30;
                    HotCheck = .50;
                    ShieldCheck = .15;
                }

                if (Guy.Health < ShieldCheck && OriginalTarget != null)   // Target check to make sure we don't shield out of combat.
                {
                    if (Context.Party.IsBuffReady(Guy, "Priest.ShieldOther", 30))
                    {
                        StopWand();
                        Context.Party.BuffPartyMember(Guy, "Priest.ShieldOther", 30, true);
                        Healed = true;
                    }
                }

                if (Guy.Health < HealCheck)
                {
                    string HealSpell = "Priest.FlashHealOther";

                    if (Guy.Health < ShieldCheck)
                        HealSpell = "Priest.RestHealOther";

                    StopWand();
                    Context.Party.CastOnMember(Guy, HealSpell, OriginalTarget);
                    Healed = true;
                }

                if (Guy.Health < HotCheck)
                {
                    if (Context.Party.IsBuffReady(Guy, "Priest.RenewOther", 15))
                    {
                        StopWand();
                        Context.Party.BuffPartyMember(Guy, "Priest.RenewOther", 15, true);
                        Healed = true;
                    }
                }
            }

            return Healed;
        }

        public override bool CheckPartyBuffs()
        {
            // PWFort for everyone except priests.
            return Context.Party.BuffParty("Priest.PWFortOther", (26 * 60), GPlayerClass.Druid) ||
                   Context.Party.BuffParty("Priest.PWFortOther", (26 * 60), GPlayerClass.Hunter) ||
                   Context.Party.BuffParty("Priest.PWFortOther", (26 * 60), GPlayerClass.Mage) ||
                   Context.Party.BuffParty("Priest.PWFortOther", (26 * 60), GPlayerClass.Paladin) ||
                   Context.Party.BuffParty("Priest.PWFortOther", (26 * 60), GPlayerClass.Shaman) ||
                   Context.Party.BuffParty("Priest.PWFortOther", (26 * 60), GPlayerClass.Rogue) ||
                   Context.Party.BuffParty("Priest.PWFortOther", (26 * 60), GPlayerClass.Warlock) ||
                   Context.Party.BuffParty("Priest.PWFortOther", (26 * 60), GPlayerClass.Warrior);
        }

        // Flay distance is a chunk of full shadow distance, so virtualize it:
        int FlayPull
        {
            get
            {
                return (int)(PullDistance * .6666);
            }
        }

        #endregion

        #region Kill player (not very good)
        GCombatResult KillPlayer(GPlayer Target, GLocation Anchor)
        {
            Context.Log("Attempting to kill player: " + Target.Name);
            bool Moved = false;

            GSpellTimer FutileCombat = new GSpellTimer(2 * 60 * 1000, true);
            GSpellTimer MFSpam = new GSpellTimer(5 * 1000, true);
            GSpellTimer MBSpam = new GSpellTimer(9 * 1000, true);
            GSpellTimer HealSpam = new GSpellTimer(9 * 1000, true);
            GCombatResult Result = GCombatResult.Bugged;

            while (!FutileCombat.IsReadySlow)
            {
                if (!Target.IsValid)
                {
                    Result = GCombatResult.Bugged;
                    break;
                }

                if (Target.IsDead || Target.DistanceToSelf > 40.0)
                {
                    Result = GCombatResult.Success;
                    break;
                }

                if (Me.IsDead)
                {
                    Result = GCombatResult.Died;
                    break;
                }

                // Check heal:
                if (Me.Health < .80 && Shield.IsReady)
                {
                    Context.CastSpell("Priest.Shield");
                    Shield.Reset();
                    continue;
                }

                if (Me.Health < .70 && Renew.IsReady && !IsShadowform)
                {
                    Context.CastSpell("Priest.Renew");
                    Renew.Reset();
                    continue;
                }

                if (Me.Health < .50 && HealSpam.IsReady && !IsShadowform)
                {
                    Context.CastSpell("Priest.FlashHeal");
                    HealSpam.Reset();
                    continue;
                }

                // Fix heading:
                Target.Face();

                // Approach:
                if (Target.DistanceToSelf > PullDistance && !Moved && Target.DistanceToSelf < 40.0)
                {
                    Moved = true;
                    Target.Approach(PullDistance - 1.0, false);
                    continue;
                }

                // Attack:

                if (MBSpam.IsReady)
                {
                    Context.CastSpell("Priest.MindBlast");
                    MFSpam.Reset();
                    continue;
                }

                if (MFSpam.IsReady)
                {
                    Context.CastSpell("Priest.MindFlay");
                    MFSpam.Reset();
                    continue;
                }

                // Melee:
                if (Target.DistanceToSelf <= Context.MeleeDistance && !Me.IsMeleeing)
                {
                    Context.CastSpell("Common.ToggleCombat", false, true);
                    continue;
                }
            }

            GContext.Main.Movement.MoveToLocation(Anchor);
            return Result;
        }
        #endregion
    }
}