Пример #1
0
        public object Clone()
        {
            var clone = new SkillMeta(Skill);

            clone.Apply(this);
            return(clone);
        }
Пример #2
0
 /// <summary>
 /// Copy the set values of this instance to another instance
 /// Properties that have not been set will not be applied.
 /// </summary>
 /// <param name="other"></param>
 public void ApplyTo(SkillMeta other)
 {
     other.Skill                  = Skill ?? other.Skill;
     other.IsCombatOnly           = _isCombatOnly ?? other.IsCombatOnly;
     other.IsEliteOnly            = _isEliteOnly ?? other.IsEliteOnly;
     other.IsCastOnSelf           = _isCastOnSelf ?? other.IsCastOnSelf;
     other.IsAvoidanceSkill       = _isAvoidanceSkill ?? other.IsAvoidanceSkill;
     other.IsMovementSkill        = _isMovementSkill ?? other.IsMovementSkill;
     other.IsSummoningSkill       = _isSummoningSkill ?? other.IsSummoningSkill;
     other.IsDestructableSkill    = _isDestructableSkill ?? other.IsDestructableSkill;
     other.IsOffensiveSkill       = _isOffensiveSkill ?? other.IsOffensiveSkill;
     other.IsDefensiveSkill       = _isDefensiveSkill ?? other.IsDefensiveSkill;
     other.IsBuffingSkill         = _isBuffingSkill ?? other.IsBuffingSkill;
     other.IsDebuffingSkill       = _isDebuffingSkill ?? other.IsDebuffingSkill;
     other.IsAreaEffectSkill      = _isAreaEffectSkill ?? other.IsAreaEffectSkill;
     other.AreaEffectShape        = _areaEffectShape ?? other.AreaEffectShape;
     other.TargetEffectFlags      = _targetEffectFlags ?? other.TargetEffectFlags;
     other.MaxTargetDistance      = _maxTargetDistance ?? other.MaxTargetDistance;
     other.CastRange              = _maxCastDistance ?? other.CastRange;
     other.AfterUseDelay          = _afterUseDelay ?? other.AfterUseDelay;
     other.ReUseDelay             = _reUseDelay ?? other.ReUseDelay;
     other.BeforeUseDelay         = _beforeUseDelay ?? other.BeforeUseDelay;
     other.RequiredCluster        = _requiredCluster ?? other.RequiredCluster;
     other.RequiredResource       = _requiredResource ?? other.RequiredResource;
     other.CastCondition          = CastCondition ?? other.CastCondition;
     other.TargetUnitSelector     = TargetUnitSelector ?? other.TargetUnitSelector;
     other.TargetPositionSelector = TargetPositionSelector ?? other.TargetPositionSelector;
 }
Пример #3
0
        /// <summary>
        /// Get a SkillMeta object
        /// </summary>
        /// <param name="skill"></param>
        /// <returns></returns>
        public static SkillMeta GetSkillMeta(Skill skill)
        {
            SkillMeta s;
            if (_skillMetas.TryGetValue(skill, out s))
                return s;

            Logger.LogVerbose("GetSkillInfo found no SkillMeta for {0}", skill.Name);
            
            var newMeta = new SkillMeta(skill);
            SetSkillMeta(newMeta);

            return newMeta;
        }
Пример #4
0
        /// <summary>
        /// Set skill to use an SkillMeta object
        /// </summary>
        public static void SetSkillMeta(SkillMeta newMeta)
        {
            if (newMeta.Skill == null)
            {
                Logger.Log("SkillInfo set attempt without a reference to a skill");
                return;
            }

            SkillMeta oldMeta;
            if (_skillMetas.TryGetValue(newMeta.Skill, out oldMeta))
            {
                oldMeta.Apply(newMeta);
            }
            else
            {
                _skillMetas.Add(newMeta.Skill, newMeta);
            }
        }
Пример #5
0
        /// <summary>
        /// When Shadow Power should be cast
        /// </summary>
        private static bool ShadowPowerCondition(SkillMeta meta)
        {
            // Buff Already Active
            if(GetHasBuff(SNOPower.DemonHunter_ShadowPower))
                return false;

            // Not Enough Discipline
            if (Player.SecondaryResource < 14)
                return false;

            // Used Recently
            if (TimeSincePowerUse(SNOPower.DemonHunter_ShadowPower) < 4500)
                return false;

            // Low Health
            if(Player.CurrentHealthPct <= Trinity.PlayerEmergencyHealthPotionLimit && Player.SecondaryResource >= 14)
                return true;

            // Defensive Cast
            if(Player.IsRooted || TargetUtil.AnyMobsInRange(15))
                return true;

            // Spam Setting
            if(Settings.Combat.DemonHunter.SpamShadowPower)
                return true;

            return false;
        }
Пример #6
0
        /// <summary>
        /// When Preperation should be cast
        /// </summary>
        private static bool PreperationCondition(SkillMeta meta)
        {
            meta.ReUseDelay = Runes.DemonHunter.FocusedMind.IsActive ? 15000 : 500;
            meta.CastFlags = CanCastFlags.NoTimer;

            if (!Runes.DemonHunter.Punishment.IsActive && Player.SecondaryResourcePct <= Settings.Combat.DemonHunter.PreperationResourcePct)
                return true;

            if (Runes.DemonHunter.Punishment.IsActive && Player.PrimaryResourcePct <= Settings.Combat.DemonHunter.PreperationResourcePct && TargetUtil.AnyMobsInRange(80f))
                return true;

            return false;
        }
Пример #7
0
        /// <summary>
        /// When Sentry should be cast
        /// </summary>
        /// <param name="meta"></param>
        /// <returns></returns>
        private static bool SentryCondition(SkillMeta meta)
        {
            meta.CastRange = 80f;
            meta.CastFlags = CanCastFlags.NoTimer;

            if (meta.Skill.Charges == 0)
                return false;

            if (TargetUtil.AnyMobsInRange(65) && Trinity.PlayerOwnedDHSentryCount < MaxSentryCount)
                return true;

            return false;
        }
Пример #8
0
        /// <summary>
        /// When Companion should be cast
        /// </summary>
        private static bool CompanionCondition(SkillMeta meta)
        {
            meta.CastFlags = CanCastFlags.NoTimer;

            // Use Spider Slow on 4 or more trash mobs in an area or on Unique/Elite/Champion
            if (Runes.DemonHunter.SpiderCompanion.IsActive && TargetUtil.ClusterExists(25f, 4) && TargetUtil.EliteOrTrashInRange(25f))
                return true;

            //Use Bat when Hatred is Needed
            if (Runes.DemonHunter.BatCompanion.IsActive && Player.PrimaryResourceMissing >= 60)
                return true;

            // Use Boar Taunt on 3 or more trash mobs in an area or on Unique/Elite/Champion
            if (Runes.DemonHunter.BoarCompanion.IsActive && ((TargetUtil.ClusterExists(20f, 4) && TargetUtil.EliteOrTrashInRange(20f)) || (CurrentTarget.IsBossOrEliteRareUnique && CurrentTarget.Distance <= 20f)))
                return true;

            // Ferrets used for picking up Health Globes when low on Health
            if (Runes.DemonHunter.FerretCompanion.IsActive && Trinity.ObjectCache.Any(o => o.Type == TrinityObjectType.HealthGlobe && o.Distance < 60f) && Player.CurrentHealthPct < EmergencyHealthPotionLimit)
                return true;

            // Use Wolf Howl on Unique/Elite/Champion - Would help for farming trash, but trash farming should not need this - Used on Elites to reduce Deaths per hour
            if (Runes.DemonHunter.WolfCompanion.IsActive && (TargetUtil.AnyElitesInRange(100f) || TargetUtil.AnyMobsInRange(40, 8)))            
                return true;

            // Companion off CD
            if (Settings.Combat.DemonHunter.CompanionOffCooldown && TargetUtil.AnyMobsInRange(60))
                return true;
            
            return false;
        }
Пример #9
0
        /// <summary>
        /// When Vault should be cast
        /// </summary>
        private static bool VaultCondition(SkillMeta meta)
        {
            meta.CastRange = 20f;
            meta.TargetPositionSelector = ret => NavHelper.MainFindSafeZone(Player.Position, true);            
            meta.RequiredResource = Hotbar.Contains(SNOPower.DemonHunter_ShadowPower) ? 22 : 16;
            meta.ReUseDelay = Settings.Combat.DemonHunter.VaultMovementDelay;

            if (Settings.Combat.DemonHunter.VaultMode == DemonHunterVaultMode.MovementOnly && IsInCombat)
                return false;

            if (Settings.Combat.DemonHunter.VaultMode == DemonHunterVaultMode.CombatOnly && !IsInCombat)
                return false;

            if (!Player.IsRooted && (TargetUtil.AnyMobsInRange(7f, 6) || Player.CurrentHealthPct <= 0.7))
                return true;

            return false;
        }
Пример #10
0
        /// <summary>
        /// When Multishot should be cast
        /// </summary>
        private static bool MultiShotCondition(SkillMeta meta)
        {
            meta.CastRange = 70f;
            meta.CastFlags = CanCastFlags.NoPowerManager;
            meta.TargetUnitSelector = ret => TargetUtil.GetClosestUnit();

            // Natalyas - Wait for damage buff
            if (Sets.NatalyasVengeance.IsFullyEquipped && Player.PrimaryResource < 100 && !CacheData.Buffs.HasBuff(SNOPower.P2_ItemPassive_Unique_Ring_053))
                return false;

            if (Sets.UnhallowedEssence.IsMaxBonusActive && TargetUtil.AnyMobsInRange(80f) || TargetUtil.ClusterExists(45, 2))
                return true;
            
            return false;
        }
Пример #11
0
 /// <summary>
 /// Where Spike trap should be cast
 /// </summary>
 private static Vector3 SpikeTrapTargetSelector(SkillMeta skillMeta)
 {
     // For distant monsters, try to target a little bit in-front of them (as they run towards us), if it's not a treasure goblin
     float reducedDistance = 0f;
     if (CurrentTarget.Distance > 17f && !CurrentTarget.IsTreasureGoblin)
     {
         reducedDistance = CurrentTarget.Distance - 17f;
         if (reducedDistance > 5f)
             reducedDistance = 5f;
     }
     return MathEx.CalculatePointFrom(CurrentTarget.Position, Player.Position, CurrentTarget.Distance - reducedDistance);
 }
Пример #12
0
 /// <summary>
 /// When Bolas should be cast
 /// </summary>
 private static bool BolasCondition(SkillMeta meta)
 {
     meta.CastRange = 50f;
     return true;
 }
Пример #13
0
 /// <summary>
 /// When Grenade should be cast
 /// </summary>
 private static bool GrenadeCondition(SkillMeta meta)
 {
     meta.CastRange = 40f;
     return true;
 }
Пример #14
0
 public object Clone()
 {
     var clone = new SkillMeta(Skill);
     clone.Apply(this);
     return clone;
 }
Пример #15
0
 /// <summary>
 /// Copy the set values of this instance to another instance
 /// Properties that have not been set will not be applied.
 /// </summary>
 /// <param name="other"></param>
 public void ApplyTo(SkillMeta other)
 {
     other.Skill = Skill ?? other.Skill;
     other.IsCombatOnly = _isCombatOnly ?? other.IsCombatOnly;
     other.IsEliteOnly = _isEliteOnly ?? other.IsEliteOnly;
     other.IsCastOnSelf = _isCastOnSelf ?? other.IsCastOnSelf;
     other.IsAvoidanceSkill = _isAvoidanceSkill ?? other.IsAvoidanceSkill;
     other.IsMovementSkill = _isMovementSkill ?? other.IsMovementSkill;
     other.IsSummoningSkill = _isSummoningSkill ?? other.IsSummoningSkill;
     other.IsDestructableSkill = _isDestructableSkill ?? other.IsDestructableSkill;
     other.IsOffensiveSkill = _isOffensiveSkill ?? other.IsOffensiveSkill;
     other.IsDefensiveSkill = _isDefensiveSkill ?? other.IsDefensiveSkill;
     other.IsBuffingSkill = _isBuffingSkill ?? other.IsBuffingSkill;
     other.IsDebuffingSkill = _isDebuffingSkill ?? other.IsDebuffingSkill;
     other.IsAreaEffectSkill = _isAreaEffectSkill ?? other.IsAreaEffectSkill;
     other.AreaEffectShape = _areaEffectShape ?? other.AreaEffectShape;
     other.TargetEffectFlags = _targetEffectFlags ?? other.TargetEffectFlags;
     other.MaxTargetDistance = _maxTargetDistance ?? other.MaxTargetDistance;
     other.CastRange = _maxCastDistance ?? other.CastRange;
     other.AfterUseDelay = _afterUseDelay ?? other.AfterUseDelay;
     other.ReUseDelay = _reUseDelay ?? other.ReUseDelay;
     other.BeforeUseDelay = _beforeUseDelay ?? other.BeforeUseDelay;
     other.RequiredCluster = _requiredCluster ?? other.RequiredCluster;
     other.RequiredResource = _requiredResource ?? other.RequiredResource;
     other.CastCondition = CastCondition ?? other.CastCondition;
     other.TargetUnitSelector = TargetUnitSelector ?? other.TargetUnitSelector;
     other.TargetPositionSelector = TargetPositionSelector ?? other.TargetPositionSelector;
 }
Пример #16
0
 /// <summary>
 /// When Entangling Shot should be cast
 /// </summary>
 private static bool EntanglingShotCondition(SkillMeta meta)
 {
     meta.CastRange = 50f;
     return true;
 }
Пример #17
0
        /// <summary>
        /// When spike trap should be cast
        /// </summary>
        private static bool SpikeTrapCondition(SkillMeta meta)
        {
            meta.TargetPositionSelector = SpikeTrapTargetSelector;

            if (LastPowerUsed != SNOPower.DemonHunter_SpikeTrap)
                return true;

            return false;
        }
Пример #18
0
 /// <summary>
 /// When Hungering Arrow should be cast
 /// </summary>
 private static bool HungeringArrowCondition(SkillMeta meta)
 {
     meta.CastRange = 50f;
     return true;
 }
Пример #19
0
        /// <summary>
        /// When Strafe should be cast
        /// </summary>
        private static bool StrafeCondition(SkillMeta meta)
        {
            meta.CastRange = 65f;
            //meta.ReUseDelay = 250;
            meta.TargetPositionSelector = ret =>
            {
                var kitePoint = NavHelper.FindSafeZone(false, 0, CurrentTarget.Position, true, Trinity.ObjectCache, false);
                if (kitePoint == Vector3.Zero)
                {
                    return TargetUtil.GetZigZagTarget(CurrentTarget.Position, V.F("Barbarian.Whirlwind.ZigZagDistance"));
                }
                else
                {
                    return kitePoint;
                }
                
            };
            //meta.TargetPositionSelector = ret => NavHelper.FindSafeZone(false, 0, CurrentTarget.Position, true, Trinity.ObjectCache, false);
            meta.CastFlags = CanCastFlags.NoTimer;
            meta.RequiredResource = Math.Max(Settings.Combat.DemonHunter.StrafeMinHatred, 12);

            if (!Player.IsRooted)
                return true;

            return false;
        }
Пример #20
0
        /// <summary>
        /// When Evasive fire should be cast
        /// </summary>
        /// <param name="meta"></param>
        /// <returns></returns>
        private static bool EvasiveFireCondition(SkillMeta meta)
        {
            if (Skills.DemonHunter.Multishot.IsActive || Skills.DemonHunter.Strafe.IsActive)
            {
                // Still generates resource when hitting nothing.

                if(CurrentTarget.IsBoss && !ShouldRefreshBastiansGeneratorBuff)
                    meta.CastRange = Skills.DemonHunter.Multishot.IsActive ? 80f : 40f;

                meta.TargetUnitSelector = ret => TargetUtil.GetClosestUnit();
            }

            if (Legendary.YangsRecurve.IsEquipped && Legendary.DeadMansLegacy.IsEquipped)
            {
                // Only use when we have to, it deals basically no damage, just generates resource and bastians buff.
                return (Player.PrimaryResourcePct < 0.5 || ShouldRefreshBastiansGeneratorBuff) && TargetUtil.AnyMobsInRange(80f);
            }

            return TargetUtil.AnyMobsInRange(80f);
        }
Пример #21
0
        /// <summary>
        /// When Fan of Knives should be cast
        /// </summary>
        private static bool FanOfKnivesCondition(SkillMeta meta)
        {
            meta.CastRange = 25f;

            if (TargetUtil.EliteOrTrashInRange(15) || TargetUtil.AnyTrashInRange(15f, 5, false))
                return true;

            return false;
        }
Пример #22
0
        /// <summary>
        /// When Impale should be cast
        /// </summary>
        private static bool ImpaleCondition(SkillMeta meta)
        {
            meta.CastRange = 80f;

            // Not enough resource
            if (Player.PrimaryResource <= EnergyReserve)
                return false;

            if (!TargetUtil.AnyMobsInRange(12, 4) && CurrentTarget.RadiusDistance <= 75f)
                return true;
            
            return false;
        }
Пример #23
0
        /// <summary>
        /// When Marked for Death should be cast
        /// </summary>
        private static bool MarkedForDeathCondition(SkillMeta meta)
        {
            meta.CastRange = 100f;
            meta.CastFlags = CanCastFlags.NoTimer;

            if (!CurrentTarget.HasDebuff(SNOPower.DemonHunter_MarkedForDeath) && !SpellTracker.IsUnitTracked(CurrentTarget, SNOPower.DemonHunter_MarkedForDeath))                
                return true;

            return false;
        }
Пример #24
0
        /// <summary>
        /// When Rapid Fire should be cast
        /// </summary>
        /// <param name="meta"></param>
        /// <returns></returns>
        private static bool RapidFireCondition(SkillMeta meta)
        {
            meta.CastFlags = CanCastFlags.NoTimer;
            meta.CastRange = 45f;

            // Stay above minimum resource level
            if (Player.PrimaryResource < EnergyReserve || Player.PrimaryResource < Settings.Combat.DemonHunter.RapidFireMinHatred)
                return false;

            // Never use it twice in a row
            if (LastPowerUsed == SNOPower.DemonHunter_RapidFire)
                return false;

            return true;
        }
Пример #25
0
 /// <summary>
 /// When Caltrops should be cast
 /// </summary>
 private static bool CaltropsCondition(SkillMeta meta)
 {        
     return TargetUtil.AnyMobsInRange(40) && !GetHasBuff(SNOPower.DemonHunter_Caltrops);
 }
Пример #26
0
        /// <summary>
        /// When Chakram should be cast.
        /// </summary>
        private static bool ChakramCondition(SkillMeta meta)
        {
            meta.CastRange = 50f;

            // Spam it for Shuriken Cloud buff
            if (Runes.DemonHunter.ShurikenCloud.IsActive && TimeSincePowerUse(SNOPower.DemonHunter_Chakram) >= 110000 &&
                ((Player.PrimaryResource >= 10 && !IsWaitingForSpecial) || Player.PrimaryResource >= MinEnergyReserve))
                return true;

            // Always cast with Spines of Seething Hatred rune, grants 4 hatred
            if (Legendary.SpinesOfSeethingHatred.IsEquipped)
                return true;

            // Monsters nearby
            if (TargetUtil.ClusterExists(45f,4))
                return true;       

            return false;
        }
Пример #27
0
        /// <summary>
        /// When Rain of Vengeance should be cast
        /// </summary>
        private static bool RainOfVengeanceCondition(SkillMeta meta)
        {
            meta.CastRange = 90f;            
            meta.CastFlags = CanCastFlags.NoTimer;

            if (Legendary.CrashingRain.IsEquipped)
                meta.TargetPositionSelector = skillMeta => TargetUtil.GetBestClusterPoint(30f, 80f); 

            if (Settings.Combat.DemonHunter.RainOfVengeanceOffCD || Sets.NatalyasVengeance.IsEquipped)
                return true;

            if (TargetUtil.ClusterExists(45f, 4) || TargetUtil.AnyElitesInRange(90f))
                return true;

            return false;
        }
Пример #28
0
        /// <summary>
        /// When Cluster Arrow should be cast
        /// </summary>
        private static bool ClusterArrowCondition(SkillMeta meta)
        {
            meta.CastRange = 85f;

            // Natalyas - Wait for damage buff
            if (Sets.NatalyasVengeance.IsFullyEquipped && Player.PrimaryResource < 100 && !CacheData.Buffs.HasBuff(SNOPower.P2_ItemPassive_Unique_Ring_053))
                return false;

            // Stay above minimum resource level
            if (Player.PrimaryResource < EnergyReserve)
                return false;

            return true;
        }
Пример #29
0
        /// <summary>
        /// When Smoke Screen should be cast
        /// </summary>
        private static bool SmokeScreenCondition(SkillMeta meta)
        {
            meta.CastFlags = CanCastFlags.NoTimer;

            // Buff Already Active
            if (GetHasBuff(SNOPower.DemonHunter_ShadowPower))
                return false;

            // Mobs in range
            if (TargetUtil.AnyMobsInRange(15) || (Legendary.MeticulousBolts.IsEquipped && TargetUtil.AnyMobsInRange(60)))
                return true;

            // Defensive Cast
            if((Player.CurrentHealthPct <= 0.50 || Player.IsRooted || Player.IsIncapacitated))
                return true;

            // Spam Setting
            if (Settings.Combat.DemonHunter.SpamSmokeScreen)
                return true;

            return false;
        }
Пример #30
0
        /// <summary>
        /// When Elemental Arrow should be cast
        /// </summary>
        private static bool ElementalArrowCondition(SkillMeta meta)
        {
            meta.CastRange = 100f;

            // Stay above minimum resource level
            if (Player.PrimaryResource < EnergyReserve && !Legendary.Kridershot.IsEquipped)
                return false;

            // Lightning DH
            if (Runes.DemonHunter.BallLightning.IsActive && Legendary.MeticulousBolts.IsEquipped)
                meta.CastRange = 15f;

            // Kridershot
            if (Legendary.Kridershot.IsEquipped)
                meta.CastRange = 65f;

            return true;
        }
Пример #31
0
        /// <summary>
        /// When Vengeance should be cast
        /// </summary>
        private static bool VengeanceCondition(SkillMeta meta)
        {
            meta.CastFlags = CanCastFlags.NoTimer;

            if (!Settings.Combat.DemonHunter.VengeanceElitesOnly && TargetUtil.AnyMobsInRange(60f, 6))
                return true;

            if (TargetUtil.IsEliteTargetInRange(100f))
                return true;

            return false;
        }
Пример #32
0
        /// <summary>
        /// When Preperation should be cast
        /// </summary>
        private static bool PreperationCondition(SkillMeta meta)
        {
            meta.ReUseDelay = Runes.DemonHunter.FocusedMind.IsActive ? 15000 : 500;
            meta.CastFlags = CanCastFlags.NoTimer;
            
            if (!Runes.DemonHunter.Punishment.IsActive && Player.SecondaryResource <= V.F("DemonHunter.MinPreparationDiscipline"))
                return true;

            if (Runes.DemonHunter.Punishment.IsActive && Player.PrimaryResource <= 75 && (TargetUtil.AnyElitesInRange(50f) || Enemies.Nearby.UnitCount > 5))
                return true;

            return false;
        }