public override void Initialize() { WaitVars = new WaitLoops(0, 1, true); Cost = 10; if (RuneIndex != 4) { IsDestructiblePower = true; Range = 50; Priority = SkillPriority.Medium; PreCast = new SkillPreCast((SkillPrecastFlags.CheckPlayerIncapacitated | SkillPrecastFlags.CheckEnergy)); ClusterConditions.Add(new SkillClusterConditions(4d, 40, 2, true)); SingleUnitCondition.Add(new UnitTargetConditions(TargetProperties.None, maxdistance: 50, MinimumHealthPercent: 0.95d, falseConditionalFlags: TargetProperties.Normal)); FcriteriaCombat = (u) => !FunkyGame.Hero.Class.bWaitingForSpecial && ((!Hotbar.HasPower(SNOPower.DemonHunter_ClusterArrow)) || LastUsedMilliseconds >= 110000); } else { //Shuriken Cloud _executiontype = SkillExecutionFlags.Buff; PreCast = new SkillPreCast(SkillPrecastFlags.CheckCanCast); Priority = SkillPriority.High; IsBuff = true; FcriteriaBuff = () => !Hotbar.HasBuff(SNOPower.DemonHunter_Chakram); FcriteriaCombat = (u) => !Hotbar.HasBuff(SNOPower.DemonHunter_Chakram); } }
public override void Initialize() { Priority = SkillPriority.High; PreCast = new SkillPreCast((SkillPrecastFlags.CheckCanCast | SkillPrecastFlags.CheckPlayerIncapacitated)); FcriteriaBuff = () => !Hotbar.HasBuff(SNOPower.X1_Barbarian_WarCry_v2); SingleUnitCondition.Add(new UnitTargetConditions(TargetProperties.None, 50)); FcriteriaCombat = (u) => (!Hotbar.HasBuff(SNOPower.X1_Barbarian_WarCry_v2) || (Hotbar.PassivePowers.Contains(SNOPower.Barbarian_Passive_InspiringPresence) && LastUsedMilliseconds > 59) || FunkyGame.Hero.dCurrentEnergyPct < (FunkyGame.Hero.Class.ContainsAnyPrimarySkill?0.10:0.50)); //10% with a primary skill, 50% without one! }
internal bool HasSpecialMovementBuff() { if (AC == ActorClass.Witchdoctor) { return(Hotbar.HasBuff(SNOPower.Witchdoctor_SpiritWalk)); } if (AC == ActorClass.Crusader) { return(Hotbar.HasBuff(SNOPower.X1_Crusader_SteedCharge)); } return(false); }
public override void Initialize() { Priority = SkillPriority.Medium; PreCast = new SkillPreCast { Flags = SkillPrecastFlags.CheckRecastTimer | SkillPrecastFlags.CheckPlayerIncapacitated | SkillPrecastFlags.CheckCanCast, }; PreCast.Criteria += skill => Hotbar.HasBuff(SNOPower.Barbarian_Revenge_Buff); PreCast.CreatePrecastCriteria(); SingleUnitCondition.Add(new UnitTargetConditions(TargetProperties.None, 10, falseConditionalFlags: TargetProperties.Normal)); ClusterConditions.Add(new SkillClusterConditions(5d, 7, 2, false, useRadiusDistance: true)); }
public override void Initialize() { Priority = SkillPriority.High; Cost = 20; Range = 35; PreCast = new SkillPreCast((SkillPrecastFlags.CheckPlayerIncapacitated | SkillPrecastFlags.CheckCanCast)); FcriteriaBuff = () => !Hotbar.HasBuff(SNOPower.Barbarian_BattleRage); FcriteriaCombat = (u) => !Hotbar.HasBuff(SNOPower.Barbarian_BattleRage) || //Only if we cannot spam sprint.. (!Hotbar.HasPower(SNOPower.Barbarian_Sprint) && ((FunkyBaseExtension.Settings.Barbarian.bFuryDumpWrath && FunkyGame.Hero.dCurrentEnergyPct >= 0.98 && Hotbar.HasBuff(SNOPower.Barbarian_WrathOfTheBerserker) && FunkyGame.Hero.dCurrentHealthPct > 0.50d) || (FunkyBaseExtension.Settings.Barbarian.bFuryDumpAlways && FunkyGame.Hero.dCurrentEnergyPct >= 0.98 && FunkyGame.Hero.dCurrentHealthPct > 0.50d))); }
internal static bool DeathShouldWait(object ret) { //if (!UIElements.ReviveAtCorpseButton.IsEnabled) // return true; if (FunkyBaseExtension.Settings.Death.WaitForPotionCooldown) { //Check Potion Cast Flags.. PowerManager.CanCastFlags potionCastFlags; if (!PowerManager.CanCast(SNOPower.DrinkHealthPotion, out potionCastFlags)) { if (potionCastFlags.HasFlag(PowerManager.CanCastFlags.PowerUnusableOnCooldown)) { BotMain.StatusText = "[Funky] Death: Waiting For Cooldowns!"; return(true); } } } if (FunkyBaseExtension.Settings.Death.WaitForAllSkillsCooldown) { //Check Archon? if (FunkyGame.Hero.Class.AC == ActorClass.Wizard && Hotbar.HasBuff(SNOPower.Wizard_Archon)) { Skill cancelSkill = FunkyGame.Hero.Class.Abilities[SNOPower.Wizard_Archon_Cancel]; Skill.UsePower(ref cancelSkill); Hotbar.RefreshHotbar(); BotMain.StatusText = "[Funky] Death: Waiting For Cooldowns!"; return(true); } foreach (var skill in Hotbar.HotbarSkills) { PowerManager.CanCastFlags skillCastFlags; if (!PowerManager.CanCast(skill.Power, out skillCastFlags)) { if (skillCastFlags.HasFlag(PowerManager.CanCastFlags.PowerUnusableOnCooldown)) { BotMain.StatusText = "[Funky] Death: Waiting For Cooldowns!"; return(true); } } } } return(false); }
internal static RunStatus DeathWaitAction(object ret) { //if (!UIElements.ReviveAtCorpseButton.IsEnabled) //{ // UIElements.ReviveAtLastCheckpointButton.Click(); //} if (FunkyBaseExtension.Settings.Death.WaitForPotionCooldown) { //Check Potion Cast Flags.. PowerManager.CanCastFlags potionCastFlags; if (!PowerManager.CanCast(SNOPower.DrinkHealthPotion, out potionCastFlags)) { if (potionCastFlags.HasFlag(PowerManager.CanCastFlags.PowerUnusableOnCooldown)) { InactivityDetector.Reset(); return(RunStatus.Running); } } } if (FunkyBaseExtension.Settings.Death.WaitForAllSkillsCooldown) { if (FunkyGame.Hero.Class.AC == ActorClass.Wizard && Hotbar.HasBuff(SNOPower.Wizard_Archon)) { Hotbar.RefreshHotbar(); InactivityDetector.Reset(); return(RunStatus.Running); } foreach (var skill in Hotbar.HotbarSkills) { PowerManager.CanCastFlags skillCastFlags; if (!PowerManager.CanCast(skill.Power, out skillCastFlags)) { if (skillCastFlags.HasFlag(PowerManager.CanCastFlags.PowerUnusableOnCooldown)) { InactivityDetector.Reset(); return(RunStatus.Running); } } } } GoldInactivity.LastCoinageUpdate = DateTime.Now; return(RunStatus.Success); }
public override void Initialize() { Priority = SkillPriority.Medium; Cost = 10; Range = 15; PreCast = new SkillPreCast((SkillPrecastFlags.CheckEnergy | SkillPrecastFlags.CheckPlayerIncapacitated)); ClusterConditions.Add(new SkillClusterConditions(10d, 30f, 2, true)); SingleUnitCondition.Add(new UnitTargetConditions(TargetProperties.None, maxdistance: 20, MinimumHealthPercent: 0.95d, falseConditionalFlags: TargetProperties.Normal)); FcriteriaCombat = (u) => !FunkyGame.Hero.Class.bWaitingForSpecial && (!FunkyBaseExtension.Settings.Barbarian.bSelectiveWhirlwind || FunkyGame.Targeting.Cache.Environment.bAnyNonWWIgnoreMobsInRange || !CacheIDLookup.hashActorSNOWhirlwindIgnore.Contains(u.SNOID)) && // If they have battle-rage, make sure it's up (!Hotbar.HasPower(SNOPower.Barbarian_BattleRage) || (Hotbar.HasPower(SNOPower.Barbarian_BattleRage) && Hotbar.HasBuff(SNOPower.Barbarian_BattleRage))); }
///<summary> ///Used to check for a secondary hotbar set. Currently only used for wizards with Archon. ///</summary> internal override bool SecondaryHotbarBuffPresent() { bool ArchonBuffPresent = Hotbar.HasBuff(SNOPower.Wizard_Archon); //Confirm we don't have archon Ability without archon buff. bool RefreshNeeded = ((!ArchonBuffPresent && (Abilities.ContainsKey(SNOPower.Wizard_Archon_ArcaneBlast) || Abilities.ContainsKey(SNOPower.Wizard_Archon_ArcaneBlast_Fire) || Abilities.ContainsKey(SNOPower.Wizard_Archon_ArcaneBlast_Cold) || Abilities.ContainsKey(SNOPower.Wizard_Archon_ArcaneBlast_Lightning))) || (ArchonBuffPresent && (!Abilities.ContainsKey(SNOPower.Wizard_Archon_ArcaneBlast) && !Abilities.ContainsKey(SNOPower.Wizard_Archon_ArcaneBlast_Fire) && !Abilities.ContainsKey(SNOPower.Wizard_Archon_ArcaneBlast_Cold) && !Abilities.ContainsKey(SNOPower.Wizard_Archon_ArcaneBlast_Lightning)))); if (RefreshNeeded) { Logger.DBLog.InfoFormat("Updating Hotbar abilities!"); Hotbar.RefreshHotbar(); RecreateAbilities(); return(true); } return(false); }
public override void Initialize() { WaitVars = new WaitLoops(0, 1, true); Cost = Equipment.CheckLegendaryItemCount(LegendaryItemTypes.InnasMantra, 3) ? 5 : 75; Priority = SkillPriority.High; PreCast = new SkillPreCast((SkillPrecastFlags.CheckCanCast)); ClusterConditions.Add(new SkillClusterConditions(7d, 35f, 2, false)); SingleUnitCondition.Add(new UnitTargetConditions(TargetProperties.None, maxdistance: 25, MinimumHealthPercent: 0.95d, falseConditionalFlags: TargetProperties.Normal)); //Sunwuko CDR Build if (Equipment.CheckLegendaryItemCount(LegendaryItemTypes.MonkeyKingsGarb, 4)) { SingleUnitCondition.Add(new UnitTargetConditions(TargetProperties.None, 25)); } FcriteriaBuff = () => { //Rune index of 4 increases duration of buff to 20 seconds.. int buffDuration = RuneIndex == 4 ? 17500 : 4500; if (FunkyBaseExtension.Settings.Monk.bMonkMaintainSweepingWind && //Maintaining Sweeping Wind (Must already have buff.. and has not used combat ability within 2000ms!) DateTime.Now.Subtract(FunkyGame.Hero.Class.LastUsedACombatAbility).TotalMilliseconds > 2000 && LastUsedMilliseconds > buffDuration && Hotbar.HasBuff(SNOPower.Monk_SweepingWind) && Hotbar.CurrentBuffs[(int)SNOPower.Monk_SweepingWind].StackCount > 1) { return(true); } return(false); }; FcriteriaCombat = (u) => { if (!Hotbar.CurrentBuffs.ContainsKey((int)SNOPower.Monk_SweepingWind)) { return(true); } return(false); }; }
public override void Initialize() { Priority = SkillPriority.Medium; Cost = 20; if (Equipment.CheckLegendaryItemCount(LegendaryItemTypes.Lamentation)) { } PreCast = new SkillPreCast((SkillPrecastFlags.CheckRecastTimer | SkillPrecastFlags.CheckEnergy | SkillPrecastFlags.CheckCanCast | SkillPrecastFlags.CheckPlayerIncapacitated)); ClusterConditions.Add(new SkillClusterConditions(5d, 8, 2, true, 0.90d)); SingleUnitCondition.Add(new UnitTargetConditions(TargetProperties.None, maxdistance: 10, falseConditionalFlags: TargetProperties.DOTDPS | TargetProperties.SucideBomber)); FcriteriaCombat = (u) => !FunkyGame.Hero.Class.bWaitingForSpecial || (FunkyBaseExtension.Settings.Barbarian.bFuryDumpWrath && FunkyGame.Hero.dCurrentEnergyPct >= 0.95 && Hotbar.HasBuff(SNOPower.Barbarian_WrathOfTheBerserker) && !FunkyGame.Hero.Class.Abilities.ContainsKey(SNOPower.Barbarian_Rend)); }
public override void Initialize() { Cooldown = 3000; WaitVars = new WaitLoops(0, 1, true); Cost = 28; SecondaryEnergy = true; Range = 0; Priority = SkillPriority.High; //PreCastFlags=, FcriteriaCombat = (u) => (!Hotbar.HasBuff(SNOPower.DemonHunter_ShadowPower) || FunkyGame.Hero.bIsIncapacitated) && (FunkyGame.Hero.dDiscipline >= 28) && (FunkyGame.Hero.dCurrentHealthPct <= 0.90 || FunkyGame.Hero.bIsRooted || FunkyGame.Targeting.Cache.Environment.iElitesWithinRange[(int)RangeIntervals.Range_20] >= 1 || FunkyGame.Targeting.Cache.Environment.iAnythingWithinRange[(int)RangeIntervals.Range_15] >= 3 || FunkyGame.Hero.bIsIncapacitated); }
public override void Initialize() { WaitVars = new WaitLoops(1, 1, true); Priority = SkillPriority.High; PreCast = new SkillPreCast((SkillPrecastFlags.CheckCanCast)); if (RuneIndex == 3) { SingleUnitCondition.Add(new UnitTargetConditions(TargetProperties.None, 20)); FcriteriaCombat = (u) => !Hotbar.HasBuff(SNOPower.Monk_BreathOfHeaven); } else { FcriteriaCombat = (u) => FunkyGame.Hero.dCurrentHealthPct <= 0.5d || FunkyGame.Targeting.Cache.Environment.iElitesWithinRange[(int)RangeIntervals.Range_25] > 0 || //with elites nearby.. FunkyGame.Targeting.Cache.Environment.iAnythingWithinRange[(int)RangeIntervals.Range_25] > 3; } FcriteriaBuff = () => FunkyGame.Hero.dCurrentHealthPct <= 0.5d; }
public override void Initialize() { Priority = SkillPriority.Medium; Cost = 20; PreCast = new SkillPreCast((SkillPrecastFlags.CheckEnergy | SkillPrecastFlags.CheckCanCast | SkillPrecastFlags.CheckPlayerIncapacitated)); FcriteriaBuff = () => FunkyBaseExtension.Settings.General.OutOfCombatMovement && !Hotbar.HasBuff(Power); FcriteriaCombat = (u) => (!Hotbar.HasBuff(SNOPower.Barbarian_Sprint) && FunkyBaseExtension.Settings.General.OutOfCombatMovement) || (((FunkyBaseExtension.Settings.Barbarian.bFuryDumpWrath && FunkyGame.Hero.dCurrentEnergyPct >= 0.95 && Hotbar.HasBuff(SNOPower.Barbarian_WrathOfTheBerserker)) || (FunkyBaseExtension.Settings.Barbarian.bFuryDumpAlways && FunkyGame.Hero.dCurrentEnergyPct >= 0.95) || ((FunkyGame.Hero.Class.Abilities[SNOPower.Barbarian_Sprint].AbilityUseTimer() && !Hotbar.HasBuff(SNOPower.Barbarian_Sprint)) && // Always keep up if we are whirlwinding, or if the target is a goblin (Hotbar.HasPower(SNOPower.Barbarian_Whirlwind) || u.IsTreasureGoblin))) && (!Hotbar.HasPower(SNOPower.Barbarian_BattleRage) || (Hotbar.HasPower(SNOPower.Barbarian_BattleRage) && Hotbar.HasBuff(SNOPower.Barbarian_BattleRage)))); }
public override void Initialize() { WaitVars = new WaitLoops(0, 0, true); Priority = SkillPriority.Medium; PreCast = new SkillPreCast { Flags = SkillPrecastFlags.CheckPlayerIncapacitated | SkillPrecastFlags.CheckCanCast, }; PreCast.Criteria += skill => !Hotbar.HasBuff(SNOPower.Witchdoctor_BigBadVoodoo); PreCast.CreatePrecastCriteria(); SingleUnitCondition.Add(new UnitTargetConditions(TargetProperties.Boss, MinimumHealthPercent: 0.95d)); SingleUnitCondition.Add(new UnitTargetConditions(TargetProperties.None, 25, MinimumHealthPercent: 0.95d, falseConditionalFlags: TargetProperties.Normal)); //Reduced CD Dagger! if (Equipment.CheckLegendaryItemCount(LegendaryItemTypes.StarmetalKukri)) { ClusterConditions.Add(new SkillClusterConditions(9d, 50f, 5, true, clusterflags: ClusterProperties.Strong)); ClusterConditions.Add(new SkillClusterConditions(9d, 50f, 10, false)); } }
internal void CreatePrecastCriteria() { SkillPrecastFlags precastconditions_ = Flags; if (precastconditions_.Equals(SkillPrecastFlags.None)) { Criteria += ((s) => true); return; } if (precastconditions_.HasFlag(SkillPrecastFlags.CheckPlayerIncapacitated)) { Criteria += ((s) => !FunkyGame.Hero.bIsIncapacitated); } if (precastconditions_.HasFlag(SkillPrecastFlags.CheckPlayerRooted)) { Criteria += ((s) => !FunkyGame.Hero.bIsRooted); } if (precastconditions_.HasFlag(SkillPrecastFlags.CheckExisitingBuff)) { Criteria += ((s) => !Hotbar.HasBuff(s.Power)); } if (precastconditions_.HasFlag(SkillPrecastFlags.CheckPetCount)) { Criteria += ((s) => FunkyGame.Hero.Class.MainPetCount < s.Counter); } if (precastconditions_.HasFlag(SkillPrecastFlags.CheckRecastTimer)) { Criteria += ((s) => s.LastUsedMilliseconds > s.Cooldown); } if (precastconditions_.HasFlag(SkillPrecastFlags.CheckEnergy)) { Criteria += ((s) => { bool energyCheck = !s.SecondaryEnergy ? FunkyGame.Hero.dCurrentEnergy >= s.Cost : FunkyGame.Hero.dDiscipline >= s.Cost; if (s.IsSpecialAbility && !energyCheck) //we trigger waiting for special here. { FunkyGame.Hero.Class.bWaitingForSpecial = true; } if (!energyCheck && (s.IsRanged || s.Range > 0)) { FunkyGame.Hero.Class.CanUseDefaultAttack = true; } return(energyCheck); }); } if (precastconditions_.HasFlag(SkillPrecastFlags.CheckCanCast)) { Criteria += ((s) => { bool cancast = PowerManager.CanCast(s.Power, out s.CanCastFlags); //PowerManager.CanCastFlags.Flag80; (Not enough Resource?) //PowerManager.CanCastFlags.Flag8; (On Cooldown?) if (!cancast && s.CanCastFlags.HasFlag(PowerManager.CanCastFlags.Flag80)) { if (s.IsSpecialAbility) { FunkyGame.Hero.Class.bWaitingForSpecial = true; } if (s.IsRanged || s.Range > 0) { FunkyGame.Hero.Class.CanUseDefaultAttack = true; } } //else if (s.IsSpecialAbility) //FunkyGame.Hero.Class.bWaitingForSpecial = false; return(cancast); }); } }
///<summary> ///Tests the given avoidance type to see if it should be ignored either due to a buff or if health is greater than the avoidance HP. ///</summary> internal static bool IgnoreAvoidance(AvoidanceType thisAvoidance) { //Pylon Shield? if (Hotbar.HasBuff(SNOPower.Pages_Buff_Invulnerable)) { return(true); } //Countess Julias Cameo (Arcane Immunity) if (Equipment.ImmuneToArcane && thisAvoidance == AvoidanceType.ArcaneSentry) { return(true); } //Maras Kaleidoscope (Poison Immunity) if (Equipment.ImmuneToPoison && (thisAvoidance == AvoidanceType.PlagueCloud || thisAvoidance == AvoidanceType.PlagueHand || thisAvoidance == AvoidanceType.PoisonGas)) { return(true); } //Talisman of Aranoch if (Equipment.ImmuneToCold && (thisAvoidance == AvoidanceType.FrozenPulse || thisAvoidance == AvoidanceType.MalthaelDeathFog)) { return(true); } //Special Blackthorne's Set Bonus Check! if (Equipment.ImmuneToDescratorMoltenPlaguedAvoidances) { switch (thisAvoidance) { case AvoidanceType.Dececrator: case AvoidanceType.MoltenCore: case AvoidanceType.MoltenTrail: case AvoidanceType.PlagueCloud: case AvoidanceType.PlagueHand: return(true); } } double dThisHealthAvoid = FunkyBaseExtension.Settings.Avoidance.Avoidances[(int)thisAvoidance].Health; //if (!FunkyGame.Hero.CriticalAvoidance) //{ //Not Critical Avoidance, should we be in total ignorance because of a buff? // Monks with Serenity up ignore all AOE's if (FunkyGame.CurrentActorClass == ActorClass.Monk) { // Monks with serenity are immune if (Hotbar.HasPower(SNOPower.Monk_Serenity) && Hotbar.HasBuff(SNOPower.Monk_Serenity)) { return(true); } //Epiphany ignore frozen. if (Hotbar.HasPower(SNOPower.X1_Monk_Epiphany) && Hotbar.HasBuff(SNOPower.X1_Monk_Epiphany) && thisAvoidance == AvoidanceType.Frozen) { return(true); } } //Crusader Akarats Champion -- Ignore Frozen! if (FunkyGame.CurrentActorClass == ActorClass.Crusader && Hotbar.HasPower(SNOPower.X1_Crusader_AkaratsChampion) && Hotbar.HasBuff(SNOPower.X1_Crusader_AkaratsChampion) && thisAvoidance == AvoidanceType.Frozen) { return(true); } if (FunkyGame.CurrentActorClass == ActorClass.Barbarian && Hotbar.HasPower(SNOPower.Barbarian_WrathOfTheBerserker) && Hotbar.HasBuff(SNOPower.Barbarian_WrathOfTheBerserker)) { switch (thisAvoidance) { case AvoidanceType.Frozen: case AvoidanceType.ArcaneSentry: case AvoidanceType.Dececrator: case AvoidanceType.PlagueCloud: return(true); } } //} //Only procedee if health percent is necessary for avoidance! return(dThisHealthAvoid < FunkyGame.Hero.dCurrentHealthPct); }
public override void Initialize() { WaitVars = new WaitLoops(1, 1, true); Cost = 30; Range = 10; Priority = SkillPriority.Medium; PreCast = new SkillPreCast((SkillPrecastFlags.CheckEnergy | SkillPrecastFlags.CheckCanCast | SkillPrecastFlags.CheckRecastTimer | SkillPrecastFlags.CheckPlayerIncapacitated)); ClusterConditions.Add(new SkillClusterConditions(4d, 18f, 3, true)); SingleUnitCondition.Add(new UnitTargetConditions(TargetProperties.None, maxdistance: 10, falseConditionalFlags: TargetProperties.Normal)); FcriteriaCombat = (u) => (!Hotbar.HasPower(SNOPower.Monk_SweepingWind) || (Hotbar.HasPower(SNOPower.Monk_SweepingWind) && Hotbar.HasBuff(SNOPower.Monk_SweepingWind))) && (!FunkyGame.Hero.Class.bWaitingForSpecial || FunkyGame.Hero.dCurrentEnergy >= FunkyGame.Hero.Class.iWaitingReservedAmount); }
internal RunStatus TargetMoveTo(CacheObject obj) { #region DebugInfo if (FunkyBaseExtension.Settings.Debugging.DebugStatusBar) { string Action = "[Move-"; switch (obj.targetType.Value) { case TargetType.Avoidance: Action += "Avoid] "; break; case TargetType.Fleeing: Action += "Flee] "; break; case TargetType.Backtrack: Action += "BackTrack] "; break; case TargetType.LineOfSight: Action += "LOS] "; break; case TargetType.Unit: if (FunkyGame.Navigation.groupRunningBehavior && FunkyGame.Navigation.groupingCurrentUnit != null && FunkyGame.Navigation.groupingCurrentUnit == obj) { Action += "Grouping] "; } else { Action += "Combat] "; } break; case TargetType.Item: case TargetType.Gold: case TargetType.Globe: Action += "Pickup] "; break; case TargetType.Interactable: Action += "Interact] "; break; case TargetType.Container: Action += "Open] "; break; case TargetType.Destructible: case TargetType.Barricade: Action += "Destroy] "; break; case TargetType.Shrine: Action += "Click] "; break; } FunkyGame.sStatusText = Action + " "; FunkyGame.sStatusText += "Target=" + FunkyGame.Targeting.Cache.CurrentTarget.InternalName + " C-Dist=" + Math.Round(FunkyGame.Targeting.Cache.CurrentTarget.CentreDistance, 2) + ". " + "R-Dist=" + Math.Round(FunkyGame.Targeting.Cache.CurrentTarget.RadiusDistance, 2) + ". "; if (FunkyGame.Targeting.Cache.CurrentTarget.targetType.Value == TargetType.Unit && FunkyGame.Hero.Class.PowerPrime.Power != SNOPower.None) { FunkyGame.sStatusText += "Power=" + FunkyGame.Hero.Class.PowerPrime.Power + " (range " + FunkyGame.Hero.Class.PowerPrime.MinimumRange + ") "; } FunkyGame.sStatusText += "Weight=" + FunkyGame.Targeting.Cache.CurrentTarget.Weight; BotMain.StatusText = FunkyGame.sStatusText; FunkyGame.bResetStatusText = true; } #endregion // Are we currently incapacitated? If so then wait... if (FunkyGame.Hero.bIsIncapacitated || FunkyGame.Hero.bIsRooted) { return(RunStatus.Running); } //Ignore skip ahead cache for LOS movements.. if (FunkyBaseExtension.Settings.Debugging.SkipAhead && obj.targetType.Value != TargetType.LineOfSight) { SkipAheadCache.RecordSkipAheadCachePoint(); } // Some stuff to avoid spamming usepower EVERY loop, and also to detect stucks/staying in one place for too long bool bForceNewMovement = false; //Herbfunk: Added this to prevent stucks attempting to move to a target blocked. (Case: 3 champs behind a wall, within range but could not engage due to being on the other side.) #region Non Movement Counter Reached if (NonMovementCounter > FunkyBaseExtension.Settings.Plugin.MovementNonMovementCount) { Logger.Write(LogLevel.Movement, "non movement counter reached {0}", NonMovementCounter); if (obj.Actortype.HasValue && obj.Actortype.Value.HasFlag(ActorType.Item)) { if (NonMovementCounter > 250) { //Are we stuck? if (!Navigation.Navigation.MGP.CanStandAt(FunkyGame.Hero.Position)) { Logger.DBLog.InfoFormat("Character is stuck inside non-standable location.. attempting townportal cast.."); ZetaDia.Me.UseTownPortal(); NonMovementCounter = 0; return(RunStatus.Running); } } //Check if we can walk to this location from current location.. if (!Navigation.Navigation.CanRayCast(FunkyGame.Hero.Position, CurrentTargetLocation, UseSearchGridProvider: true)) { obj.RequiresLOSCheck = true; obj.BlacklistLoops = 50; Logger.Write(LogLevel.Movement, "Ignoring Item {0} -- due to RayCast Failure!", obj.InternalName); FunkyGame.Targeting.Cache.bForceTargetUpdate = true; return(RunStatus.Running); } } else if (ObjectCache.CheckFlag(obj.targetType.Value, TargetType.LineOfSight | TargetType.Backtrack)) { Logger.Write(LogLevel.LineOfSight, "Line of Sight Movement Stalled!"); //FunkyGame.Navigation.LOSmovementObject = null; Navigation.Navigation.NP.Clear(); FunkyGame.Targeting.Cache.bForceTargetUpdate = true; NonMovementCounter = 0; // Reset the emergency loop counter and return success return(RunStatus.Running); } else { Logger.Write(LogLevel.Movement, "Ignoring obj {0} ", obj.InternalName + " _ SNO:" + obj.SNOID); obj.BlacklistLoops = 50; obj.RequiresLOSCheck = true; FunkyGame.Targeting.Cache.bForceTargetUpdate = true; NonMovementCounter = 0; // Reset the emergency loop counter and return success return(RunStatus.Running); } } #endregion //Do a priority check for nearby obstacle objects. FunkyGame.Navigation.ObstaclePrioritizeCheck(15f); #region Evaluate Last Action // Position didn't change last update.. check if we are stuck! if (DateTime.Now.Subtract(lastPositionChange).TotalMilliseconds > 150 && (!FunkyGame.Hero.IsMoving || FunkyGame.Hero.currentMovementState == MovementState.WalkingInPlace || FunkyGame.Hero.currentMovementState.Equals(MovementState.None))) { bForceNewMovement = true; if (DateTime.Now.Subtract(LastMovementDuringCombat).TotalMilliseconds >= 250) { LastMovementDuringCombat = DateTime.Now; BlockedMovementCounter++; // Tell target finder to prioritize close-combat targets incase we were bodyblocked #region TargetingPriortize switch (BlockedMovementCounter) { case 2: case 3: if (FunkyGame.Navigation.groupRunningBehavior) { Logger.Write(LogLevel.Movement, "Grouping Behavior stopped due to blocking counter"); FunkyGame.Navigation.GroupingFinishBehavior(); FunkyGame.Navigation.groupingSuspendedDate = DateTime.Now.AddMilliseconds(4000); FunkyGame.Targeting.Cache.bForceTargetUpdate = true; return(RunStatus.Running); } if (!ObjectCache.CheckFlag(obj.targetType.Value, TargetType.AvoidanceMovements)) { //Finally try raycasting to see if navigation is possible.. if (obj.Actortype.HasValue && (obj.Actortype.Value == ActorType.Gizmo || obj.Actortype.Value == ActorType.Monster)) { Vector3 hitTest; // No raycast available, try and force-ignore this for a little while, and blacklist for a few seconds if (Navigator.Raycast(FunkyGame.Hero.Position, obj.Position, out hitTest)) { if (hitTest != Vector3.Zero) { obj.RequiresLOSCheck = true; obj.BlacklistLoops = 10; Logger.Write(LogLevel.Movement, "Ignoring object " + obj.InternalName + " due to not moving and raycast failure!", true); FunkyGame.Targeting.Cache.bForceTargetUpdate = true; return(RunStatus.Running); } } } else if (obj.targetType.Value == TargetType.Item) { obj.BlacklistLoops = 10; FunkyGame.Targeting.Cache.bForceTargetUpdate = true; } } else { if (!Navigation.Navigation.CanRayCast(FunkyGame.Hero.Position, CurrentTargetLocation, NavCellFlags.AllowWalk)) { Logger.Write(LogLevel.Movement, "Cannot continue with avoidance movement due to raycast failure!"); BlockedMovementCounter = 0; FunkyGame.Navigation.CurrentGPArea.BlacklistLastSafespot(); FunkyGame.Navigation.vlastSafeSpot = Vector3.Zero; FunkyGame.Targeting.Cache.bForceTargetUpdate = true; return(RunStatus.Running); } } break; } #endregion return(RunStatus.Running); } } else { // Movement has been made, so count the time last moved! LastMovementDuringCombat = DateTime.Now; } #endregion // See if we want to ACTUALLY move, or are just waiting for the last move command... if (!bForceNewMovement && IsAlreadyMoving && CurrentTargetLocation == LastTargetLocation && DateTime.Now.Subtract(LastMovementCommand).TotalMilliseconds <= 100) { return(RunStatus.Running); } // If we're doing avoidance, globes or backtracking, try to use special abilities to move quicker #region SpecialMovementChecks if (ObjectCache.CheckFlag(obj.targetType.Value, FunkyBaseExtension.Settings.Combat.CombatMovementTargetTypes)) { Skill MovementPower; Vector3 MovementVector = FunkyGame.Hero.Class.FindCombatMovementPower(out MovementPower, obj.Position); if (MovementVector != Vector3.Zero) { ZetaDia.Me.UsePower(MovementPower.Power, MovementVector, FunkyGame.Hero.CurrentWorldDynamicID, -1); MovementPower.OnSuccessfullyUsed(); // Store the current destination for comparison incase of changes next loop LastTargetLocation = CurrentTargetLocation; // Reset total body-block count, since we should have moved //if (DateTime.Now.Subtract(FunkyGame.Targeting.Cache.Environment.lastForcedKeepCloseRange).TotalMilliseconds>=2000) BlockedMovementCounter = 0; FunkyGame.Hero.Class.PowerPrime.WaitLoopsBefore = 5; return(RunStatus.Running); } //Special Whirlwind Code if (FunkyGame.Hero.Class.AC == ActorClass.Barbarian && Hotbar.HasPower(SNOPower.Barbarian_Whirlwind)) { // Whirlwind against everything within range (except backtrack points) if (FunkyGame.Hero.dCurrentEnergy >= 10 && FunkyGame.Targeting.Cache.Environment.iAnythingWithinRange[(int)RangeIntervals.Range_20] >= 1 && obj.DistanceFromTarget <= 12f && (!Hotbar.HasPower(SNOPower.Barbarian_Sprint) || Hotbar.HasBuff(SNOPower.Barbarian_Sprint)) && (ObjectCache.CheckFlag(obj.targetType.Value, TargetType.AvoidanceMovements | TargetType.Gold | TargetType.Globe) == false) && (obj.targetType.Value != TargetType.Unit || (obj.targetType.Value == TargetType.Unit && !obj.IsTreasureGoblin && (!FunkyBaseExtension.Settings.Barbarian.bSelectiveWhirlwind || FunkyGame.Targeting.Cache.Environment.bAnyNonWWIgnoreMobsInRange || !CacheIDLookup.hashActorSNOWhirlwindIgnore.Contains(obj.SNOID))))) { // Special code to prevent whirlwind double-spam, this helps save fury bool bUseThisLoop = SNOPower.Barbarian_Whirlwind != FunkyGame.Hero.Class.LastUsedAbility.Power; if (!bUseThisLoop) { if (FunkyGame.Hero.Class.Abilities[SNOPower.Barbarian_Whirlwind].LastUsedMilliseconds >= 200) { bUseThisLoop = true; } } if (bUseThisLoop) { ZetaDia.Me.UsePower(SNOPower.Barbarian_Whirlwind, CurrentTargetLocation, FunkyGame.Hero.CurrentWorldDynamicID); FunkyGame.Hero.Class.Abilities[SNOPower.Barbarian_Whirlwind].OnSuccessfullyUsed(); } // Store the current destination for comparison incase of changes next loop LastTargetLocation = CurrentTargetLocation; BlockedMovementCounter = 0; return(RunStatus.Running); } } } #endregion //Special Movement Check for Steed Charge and Spirit Walk if (FunkyGame.Hero.Class.LastUsedAbility.IsSpecialMovementSkill && FunkyGame.Hero.Class.HasSpecialMovementBuff() && ObjectCache.CheckFlag(obj.targetType.Value, TargetType.Unit)) { //Logger.DBLog.DebugFormat("Preforming ZigZag for special movement skill activation!"); FunkyGame.Navigation.vPositionLastZigZagCheck = FunkyGame.Hero.Position; if (FunkyGame.Hero.Class.ShouldGenerateNewZigZagPath()) { FunkyGame.Hero.Class.GenerateNewZigZagPath(); } CurrentTargetLocation = FunkyGame.Navigation.vSideToSideTarget; } // Now for the actual movement request stuff IsAlreadyMoving = true; UseTargetMovement(obj, bForceNewMovement); // Store the current destination for comparison incase of changes next loop LastMovementAttempted = DateTime.Now; LastTargetLocation = CurrentTargetLocation; //Check if we moved at least 5f.. if (LastPlayerLocation.Distance(FunkyGame.Hero.Position) <= 5f) { NonMovementCounter++; } else { NonMovementCounter = 0; BlockedMovementCounter = 0; } //store player location LastPlayerLocation = FunkyGame.Hero.Position; return(RunStatus.Running); }