/// <summary> /// Receive Pulse event from DemonBuddy. /// </summary> public void OnPulse() { try { if (ZetaDia.Me == null) { return; } if (!ZetaDia.IsInGame || !ZetaDia.Me.IsValid || ZetaDia.IsLoadingWorld) { return; } //ScenesStorage.Update(); using (new PerformanceLogger("OnPulse")) { //if (IsMoveRequested) // NavServerReport(); GameUI.SafeClickUIButtons(); if (ZetaDia.Me.IsDead) { return; } using (new PerformanceLogger("LazyRaiderClickToPause")) { if (Settings.Advanced.LazyRaiderClickToPause && !BotMain.IsPaused) { BotMain.PauseWhile(MouseLeft); } } // See if we should update the stats file if (DateTime.UtcNow.Subtract(ItemDropStats.ItemStatsLastPostedReport).TotalSeconds > 10) { ItemDropStats.ItemStatsLastPostedReport = DateTime.UtcNow; ItemDropStats.OutputReport(); } // Recording of all the XML's in use this run UsedProfileManager.RecordProfile(); DebugUtil.LogOnPulse(); Gamble.CheckShouldTownRunForGambling(); MonkCombat.RunOngoingPowers(); } } catch (AccessViolationException) { // woof! } catch (Exception ex) { Logger.Log(LogCategory.UserInformation, "Exception in Pulse: {0}", ex.ToString()); } }
/// <summary> /// Returns an appropriately selected TrinityPower and related information /// </summary> /// <param name="IsCurrentlyAvoiding">Are we currently avoiding?</param> /// <param name="UseOOCBuff">Buff Out Of Combat</param> /// <param name="UseDestructiblePower">Is this for breaking destructables?</param> /// <returns></returns> internal static TrinityPower AbilitySelector(bool IsCurrentlyAvoiding = false, bool UseOOCBuff = false, bool UseDestructiblePower = false) { using (new PerformanceLogger("AbilitySelector")) { if (!UseOOCBuff && CurrentTarget == null) { return(new TrinityPower()); } // Switch based on the cached character class TrinityPower power = CombatBase.CurrentPower; if (Player.PrimaryResource >= MinEnergyReserve) { IsWaitingForSpecial = false; } if (Player.PrimaryResource < 20) { IsWaitingForSpecial = true; } using (new PerformanceLogger("AbilitySelector.ClassAbility")) { switch (Player.ActorClass) { // Barbs case ActorClass.Barbarian: power = BarbarianCombat.GetPower(); break; // Crusader case ActorClass.Crusader: power = CrusaderCombat.GetPower(); break; // Monks case ActorClass.Monk: power = MonkCombat.GetPower(); if (power != null && GetHasBuff(SNOPower.X1_Monk_Epiphany) && power.MinimumRange > 0) { power.MinimumRange = 75f; } break; // Wizards case ActorClass.Wizard: power = WizardCombat.GetPower(); break; // Witch Doctors case ActorClass.Witchdoctor: power = WitchDoctorCombat.GetPower(); break; // Demon Hunters case ActorClass.DemonHunter: power = DemonHunterCombat.GetPower(); break; } } // use IEquatable to check if they're equal if (CombatBase.CurrentPower == power) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Behavior, "Keeping {0}", CombatBase.CurrentPower.ToString()); return(CombatBase.CurrentPower); } else if (power != null && power.SNOPower != SNOPower.None) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Behavior, "Selected new {0}", power.ToString()); return(power); } else { return(defaultPower); } } }
/// <summary> /// Find fresh targets, start main BehaviorTree if needed, cast any buffs needed etc. /// </summary> /// <param name="ret"></param> /// <returns></returns> internal static bool TargetCheck(object ret) { Logger.LogVerbose("TargetCheck Tick"); using (new PerformanceLogger("TargetCheck")) { if (Player.IsDead) { return(TargetCheckResult(false, "Is Dead")); } _timesBlockedMoving = 0; IsAlreadyMoving = false; lastMovementCommand = DateTime.MinValue; _isWaitingForPower = false; _isWaitingAfterPower = false; _isWaitingBeforePower = false; _isWaitingForPotion = false; wasRootedLastTick = false; ClearBlacklists(); using (new PerformanceLogger("TargetCheck.RefreshCache")) { // Refresh Cache if needed RefreshDiaObjectCache(); } // We have a target, start the target handler! if (CurrentTarget != null) { _shouldPickNewAbilities = true; return(TargetCheckResult(true, "Current Target is not null")); } MonkCombat.RunOngoingPowers(); // if we just opened a horadric cache, wait around to open it if (DateTime.UtcNow.Subtract(Composites.LastFoundHoradricCache).TotalSeconds < 5) { return(TargetCheckResult(true, "Recently opened Horadric Cache")); } using (new PerformanceLogger("TargetCheck.OOCPotion")) { // Pop a potion when necessary if (Player.CurrentHealthPct <= CombatBase.EmergencyHealthPotionLimit) { UsePotionIfNeededTask(); } } _statusText = "[Trinity] No more targets - DemonBuddy/profile management is now in control"; if (Settings.Advanced.DebugInStatusBar && _resetStatusText) { _resetStatusText = false; BotMain.StatusText = _statusText; } // Nothing to do... do we have some maintenance we can do instead, like out of combat buffing? if (DateTime.UtcNow.Subtract(_lastMaintenanceCheck).TotalMilliseconds > 150) { using (new PerformanceLogger("TargetCheck.OOCBuff")) { _lastMaintenanceCheck = DateTime.UtcNow; bool isLoopingAnimation = ZetaDia.Me.LoopingAnimationEndTime > 0; if (!isLoopingAnimation && !WantToTownRun && !ForceVendorRunASAP) { BarbarianCombat.AllowSprintOOC = true; DisableOutofCombatSprint = false; powerBuff = AbilitySelector(UseOOCBuff: true); if (powerBuff.SNOPower != SNOPower.None) { Logger.Log(TrinityLogLevel.Verbose, LogCategory.Behavior, "Using OOC Buff: {0}", powerBuff.SNOPower.ToString()); ZetaDia.Me.UsePower(powerBuff.SNOPower, powerBuff.TargetPosition, powerBuff.TargetDynamicWorldId, powerBuff.TargetACDGUID); LastPowerUsed = powerBuff.SNOPower; CacheData.AbilityLastUsed[powerBuff.SNOPower] = DateTime.UtcNow; // Monk Stuffs get special attention { if (powerBuff.SNOPower == SNOPower.Monk_TempestRush) { MonkCombat.LastTempestRushLocation = CombatBase.CurrentPower.TargetPosition; } if (powerBuff.SNOPower == SNOPower.Monk_SweepingWind) { MonkCombat.LastSweepingWindRefresh = DateTime.UtcNow; } } } } else if (isLoopingAnimation) { _keepKillRadiusExtendedForSeconds = 20; _timeKeepKillRadiusExtendedUntil = DateTime.UtcNow.AddSeconds(_keepKillRadiusExtendedForSeconds); } } } CurrentTarget = null; if ((ForceVendorRunASAP || WantToTownRun) && TownRun.TownRunTimerRunning()) { Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "Waiting for town run timer (Target Check)", true); return(TargetCheckResult(true, "Waiting for TownRunTimer")); } return(TargetCheckResult(false, "End of TargetCheck")); } }