public static void ResetEverythingNewGame() { hashUseOnceID = new HashSet <int>(); dictUseOnceID = new Dictionary <int, int>(); iMaxDeathsAllowed = 0; iDeathsThisRun = 0; _hashsetItemStatsLookedAt = new HashSet <string>(); _hashsetItemPicksLookedAt = new HashSet <string>(); _hashsetItemFollowersIgnored = new HashSet <string>(); TownRun._dictItemStashAttempted = new Dictionary <int, int>(); hashRGUIDBlacklist60 = new HashSet <int>(); hashRGUIDBlacklist90 = new HashSet <int>(); hashRGUIDBlacklist15 = new HashSet <int>(); vBacktrackList = new SortedList <int, Vector3>(); iTotalBacktracks = 0; HasMappedPlayerAbilities = false; PlayerMover.iTotalAntiStuckAttempts = 1; PlayerMover.vSafeMovementLocation = Vector3.Zero; PlayerMover.vOldPosition = Vector3.Zero; PlayerMover.iTimesReachedStuckPoint = 0; PlayerMover.TimeLastRecordedPosition = DateTime.Today; PlayerMover.LastGeneratedStuckPosition = DateTime.Today; PlayerMover.iTimesReachedMaxUnstucks = 0; PlayerMover.iCancelUnstuckerForSeconds = 0; PlayerMover._lastCancelledUnstucker = DateTime.Today; NavHelper.UsedStuckSpots = new List <GridPoint>(); // Reset all the caches dictGilesObjectTypeCache = new Dictionary <int, GObjectType>(); dictGilesMonsterAffixCache = new Dictionary <int, MonsterAffixes>(); dictGilesMaxHealthCache = new Dictionary <int, double>(); dictGilesLastHealthCache = new Dictionary <int, double>(); dictGilesLastHealthChecked = new Dictionary <int, int>(); dictGilesBurrowedCache = new Dictionary <int, bool>(); dictGilesActorSNOCache = new Dictionary <int, int>(); dictGilesACDGUIDCache = new Dictionary <int, int>(); dictGilesInternalNameCache = new Dictionary <int, string>(); dictGilesGameBalanceIDCache = new Dictionary <int, int>(); dictGilesDynamicIDCache = new Dictionary <int, int>(); dictGilesVectorCache = new Dictionary <int, Vector3>(); dictGilesGoldAmountCache = new Dictionary <int, int>(); dictGilesQualityCache = new Dictionary <int, ItemQuality>(); dictGilesPickupItem = new Dictionary <int, bool>(); dictSummonedByID = new Dictionary <int, int>(); dictTotalInteractionAttempts = new Dictionary <int, int>(); listProfilesLoaded = new List <string>(); CurrentProfile = ""; FirstProfile = ""; NavHelper.UpdateSearchGridProvider(); GoldInactivity.ResetCheckGold(); global::GilesTrinity.XmlTags.TrinityLoadOnce.UsedProfiles = new List <string>(); GenericCache.ClearCache(); GenericBlacklist.ClearBlacklist(); }
/// <summary> /// Called when user disable the plugin. /// </summary> public void OnDisabled() { IsPluginEnabled = false; Navigator.PlayerMover = new DefaultPlayerMover(); Navigator.StuckHandler = new DefaultStuckHandler(); CombatTargeting.Instance.Provider = new DefaultCombatTargetingProvider(); LootTargeting.Instance.Provider = new DefaultLootTargetingProvider(); ObstacleTargeting.Instance.Provider = new DefaultObstacleTargetingProvider(); GameEvents.OnPlayerDied -= TrinityOnDeath; BotMain.OnStop -= TrinityBotStop; BotMain.OnStop -= PluginCheck; GameEvents.OnGameJoined -= TrinityOnJoinGame; GameEvents.OnGameLeft -= TrinityOnLeaveGame; DbHelper.Log(TrinityLogLevel.Normal, LogCategory.UserInformation, "*******************TRINITY*****************"); DbHelper.Log(TrinityLogLevel.Normal, LogCategory.UserInformation, "DESATIVADO: Trinity foi desligado..."); DbHelper.Log(TrinityLogLevel.Normal, LogCategory.UserInformation, "*******************TRINITY*****************"); GenericCache.Shutdown(); GenericBlacklist.Shutdown(); }
private static void RecordTargetHistory() { string targetMd5Hash = HashGenerator.GenerateObjecthash(CurrentTarget); // clean up past targets if (!GenericCache.ContainsKey(targetMd5Hash)) { CurrentTarget.HasBeenPrimaryTarget = true; CurrentTarget.TimesBeenPrimaryTarget = 1; CurrentTarget.FirstTargetAssignmentTime = DateTime.Now; GenericCache.AddToCache(new GenericCacheObject(targetMd5Hash, CurrentTarget, new TimeSpan(0, 10, 0))); } else if (GenericCache.ContainsKey(targetMd5Hash)) { GilesObject cTarget = (GilesObject)GenericCache.GetObject(targetMd5Hash).Value; if (!cTarget.IsBoss && cTarget.TimesBeenPrimaryTarget > 15 && !(cTarget.Type == GObjectType.Item && cTarget.ItemQuality >= ItemQuality.Legendary)) { DbHelper.Log(TrinityLogLevel.Normal, LogCategory.UserInformation, "Blacklisting target {0} ActorSNO={1} RActorGUID={2} due to possible stuck/flipflop!", CurrentTarget.InternalName, CurrentTarget.ActorSNO, CurrentTarget.RActorGuid); hashRGUIDBlacklist60.Add(CurrentTarget.RActorGuid); // Add to generic blacklist for safety, as the RActorGUID on items and gold can change as we move away and get closer to the items (while walking around corners) // So we can't use any ID's but rather have to use some data which never changes (actorSNO, position, type, worldID) GenericBlacklist.AddToBlacklist(new GenericCacheObject() { Key = CurrentTarget.ObjectHash, Value = null, Expires = DateTime.Now.AddSeconds(60) }); } else { cTarget.TimesBeenPrimaryTarget++; GenericCache.UpdateObject(new GenericCacheObject(targetMd5Hash, cTarget, new TimeSpan(0, 10, 0))); } } }
/// <summary> /// Called when DemonBuddy shut down. /// </summary> public void OnShutdown() { GenericCache.Shutdown(); GenericBlacklist.Shutdown(); }
private static bool RefreshUnitAttributes(bool AddToCache = true, DiaUnit unit = null) { /* * TeamID - check once for all units except bosses (which can potentially change teams - Belial, Cydea) */ string teamIdHash = HashGenerator.GetGenericHash("teamId.RActorGuid=" + c_RActorGuid + ".ActorSNO=" + c_ActorSNO + ".WorldId=" + PlayerStatus.WorldID); int teamId = 0; if (!c_unit_IsBoss && GenericCache.ContainsKey(teamIdHash)) { teamId = (int)GenericCache.GetObject(teamIdHash).Value; } else { teamId = c_CommonData.GetAttribute <int>(ActorAttributeType.TeamID); GenericCache.AddToCache(new GenericCacheObject() { Key = teamIdHash, Value = teamId, Expires = DateTime.Now.AddMinutes(60) }); } if (teamId == 1) { AddToCache = false; c_IgnoreSubStep += "IsTeam1+"; return(AddToCache); } if (unit.IsUntargetable) { AddToCache = false; c_IgnoreSubStep = "IsUntargetable"; return(AddToCache); } // don't check for invulnerability on shielded units, they are treated seperately if (!c_unit_IsShielded && unit.IsInvulnerable) { AddToCache = false; c_IgnoreSubStep = "IsInvulnerable"; return(AddToCache); } bool isBurrowed = false; if (!dictGilesBurrowedCache.TryGetValue(c_RActorGuid, out isBurrowed)) { isBurrowed = unit.IsBurrowed; // if the unit is NOT burrowed - we can attack them, add to cache (as IsAttackable) if (!isBurrowed) { dictGilesBurrowedCache.Add(c_RActorGuid, isBurrowed); } } if (isBurrowed) { AddToCache = false; c_IgnoreSubStep = "IsBurrowed"; return(AddToCache); } // only check for DotDPS/Bleeding in certain conditions to save CPU for everyone else // barbs with rend // All WD's // Monks with Way of the Hundred Fists + Fists of Fury if (AddToCache && ((PlayerStatus.ActorClass == ActorClass.Barbarian && Hotbar.Contains(SNOPower.Barbarian_Rend)) || PlayerStatus.ActorClass == ActorClass.WitchDoctor || (PlayerStatus.ActorClass == ActorClass.Monk && HotbarSkills.AssignedSkills.Any(s => s.Power == SNOPower.Monk_WayOfTheHundredFists && s.RuneIndex == 0))) ) { ////bool hasdotDPS = c_CommonData.GetAttribute<int>(ActorAttributeType.DOTDPS) != 0; //bool isBleeding = c_CommonData.GetAttribute<int>(ActorAttributeType.Bleeding) != 0; //c_HasDotDPS = hasdotDPS && isBleeding; bool hasdotDPS = c_CommonData.GetAttribute <int>(ActorAttributeType.DOTDPS) != 0; c_HasDotDPS = hasdotDPS; } return(AddToCache); }
private static bool RefreshItemStats(GItemBaseType tempbasetype) { bool isNewLogItem = false; c_ItemMd5Hash = HashGenerator.GenerateItemHash(c_Position, c_ActorSNO, c_InternalName, CurrentWorldDynamicId, c_ItemQuality, c_ItemLevel); if (!GenericCache.ContainsKey(c_ItemMd5Hash)) { GenericCache.AddToCache(new GenericCacheObject(c_ItemMd5Hash, null, new TimeSpan(1, 0, 0))); isNewLogItem = true; if (tempbasetype == GItemBaseType.Armor || tempbasetype == GItemBaseType.WeaponOneHand || tempbasetype == GItemBaseType.WeaponTwoHand || tempbasetype == GItemBaseType.WeaponRange || tempbasetype == GItemBaseType.Jewelry || tempbasetype == GItemBaseType.FollowerItem || tempbasetype == GItemBaseType.Offhand) { int iThisQuality; ItemsDroppedStats.Total++; if (c_ItemQuality >= ItemQuality.Legendary) { iThisQuality = QUALITYORANGE; } else if (c_ItemQuality >= ItemQuality.Rare4) { iThisQuality = QUALITYYELLOW; } else if (c_ItemQuality >= ItemQuality.Magic1) { iThisQuality = QUALITYBLUE; } else { iThisQuality = QUALITYWHITE; } ItemsDroppedStats.TotalPerQuality[iThisQuality]++; ItemsDroppedStats.TotalPerLevel[c_ItemLevel]++; ItemsDroppedStats.TotalPerQPerL[iThisQuality, c_ItemLevel]++; } else if (tempbasetype == GItemBaseType.Gem) { int iThisGemType = 0; ItemsDroppedStats.TotalGems++; if (c_item_GItemType == GItemType.Topaz) { iThisGemType = GEMTOPAZ; } if (c_item_GItemType == GItemType.Ruby) { iThisGemType = GEMRUBY; } if (c_item_GItemType == GItemType.Emerald) { iThisGemType = GEMEMERALD; } if (c_item_GItemType == GItemType.Amethyst) { iThisGemType = GEMAMETHYST; } ItemsDroppedStats.GemsPerType[iThisGemType]++; ItemsDroppedStats.GemsPerLevel[c_ItemLevel]++; ItemsDroppedStats.GemsPerTPerL[iThisGemType, c_ItemLevel]++; } else if (c_item_GItemType == GItemType.HealthPotion) { ItemsDroppedStats.TotalPotions++; ItemsDroppedStats.PotionsPerLevel[c_ItemLevel]++; } else if (c_item_GItemType == GItemType.InfernalKey) { ItemsDroppedStats.TotalInfernalKeys++; } // See if we should update the stats file if (DateTime.Now.Subtract(ItemStatsLastPostedReport).TotalSeconds > 10) { ItemStatsLastPostedReport = DateTime.Now; OutputReport(); } } return(isNewLogItem); }
/// <summary> /// This method will add and update necessary information about all available actors. Determines GilesObjectType, sets ranges, updates blacklists, determines avoidance, kiting, target weighting /// and the result is we will have a new target for the Target Handler. Returns true if the cache was refreshed. /// </summary> /// <returns>True if the cache was updated</returns> public static bool RefreshDiaObjectCache(bool forceUpdate = false) { using (new PerformanceLogger("RefreshDiaObjectCache")) { if (DateTime.Now.Subtract(LastRefreshedCache).TotalMilliseconds < Settings.Advanced.CacheRefreshRate && !forceUpdate) { if (!UpdateCurrentTarget()) { return(false); } } LastRefreshedCache = DateTime.Now; using (new PerformanceLogger("RefreshDiaObjectCache.UpdateBlock")) { GenericCache.MaintainCache(); GenericBlacklist.MaintainBlacklist(); using (ZetaDia.Memory.AcquireFrame()) { // Update player-data cache, including buffs GilesPlayerCache.UpdateCachedPlayerData(); if (PlayerStatus.CurrentHealthPct <= 0) { return(false); } if (Settings.Combat.Misc.UseNavMeshTargeting && !gp.CanStandAt(gp.WorldToGrid(PlayerStatus.CurrentPosition.ToVector2()))) { NavHelper.UpdateSearchGridProvider(); } RefreshCacheInit(); // Now pull up all the data and store anything we want to handle in the super special cache list // Also use many cache dictionaries to minimize DB<->D3 memory hits, and speed everything up a lot RefreshCacheMainLoop(); } } // Reduce ignore-for-loops counter if (IgnoreTargetForLoops > 0) { IgnoreTargetForLoops--; } // If we have an avoidance under our feet, then create a new object which contains a safety point to move to // But only if we aren't force-cancelling avoidance for XX time bool bFoundSafeSpot = false; using (new PerformanceLogger("RefreshDiaObjectCache.AvoidanceCheck")) { // Note that if treasure goblin level is set to kamikaze, even avoidance moves are disabled to reach the goblin! if (StandingInAvoidance && (!AnyTreasureGoblinsPresent || Settings.Combat.Misc.GoblinPriority <= GoblinPriority.Prioritize) && DateTime.Now.Subtract(timeCancelledEmergencyMove).TotalMilliseconds >= cancelledEmergencyMoveForMilliseconds) { Vector3 vAnySafePoint = NavHelper.FindSafeZone(false, 1, PlayerStatus.CurrentPosition, true); // Ignore avoidance stuff if we're incapacitated or didn't find a safe spot we could reach if (vAnySafePoint != vNullLocation) { if (Settings.Advanced.LogCategories.HasFlag(LogCategory.Movement)) { DbHelper.Log(TrinityLogLevel.Verbose, LogCategory.Movement, "Kiting Avoidance: {0} Distance: {1:0} Direction: {2:0}, Health%={3:0.00}, KiteDistance: {4:0}", vAnySafePoint, vAnySafePoint.Distance(Me.Position), MathUtil.GetHeading(MathUtil.FindDirectionDegree(Me.Position, vAnySafePoint)), PlayerStatus.CurrentHealthPct, PlayerKiteDistance); } bFoundSafeSpot = true; CurrentTarget = new GilesObject() { Position = vAnySafePoint, Type = GObjectType.Avoidance, Weight = 20000, CentreDistance = Vector3.Distance(PlayerStatus.CurrentPosition, vAnySafePoint), RadiusDistance = Vector3.Distance(PlayerStatus.CurrentPosition, vAnySafePoint), InternalName = "GilesSafePoint" };; } //else //{ // // Didn't find any safe spot we could reach, so don't look for any more safe spots for at least 2.8 seconds // cancelledEmergencyMoveForMilliseconds = 2800; // timeCancelledEmergencyMove = DateTime.Now; // DbHelper.Log(TrinityLogLevel.Verbose, LogCategory.Movement, "Unable to find kite location, canceling emergency movement for {0}ms", cancelledEmergencyMoveForMilliseconds); //} } } /* * Give weights to objects */ // Special flag for special whirlwind circumstances bAnyNonWWIgnoreMobsInRange = false; // Now give each object a weight *IF* we aren't skipping direcly to a safe-spot if (!bFoundSafeSpot) { RefreshDiaGetWeights(); RefreshSetKiting(ref vKitePointAvoid, NeedToKite, ref TryToKite); } // Not heading straight for a safe-spot? // No valid targets but we were told to stay put? if (CurrentTarget == null && ShouldStayPutDuringAvoidance && !StandingInAvoidance) { CurrentTarget = new GilesObject() { Position = PlayerStatus.CurrentPosition, Type = GObjectType.Avoidance, Weight = 20000, CentreDistance = 2f, RadiusDistance = 2f, InternalName = "GilesStayPutPoint" }; DbHelper.Log(TrinityLogLevel.Debug, LogCategory.CacheManagement, "Staying Put During Avoidance"); } using (new PerformanceLogger("RefreshDiaObjectCache.FinalChecks")) { // force to stay put if we want to town run and there's no target if (CurrentTarget == null && ForceVendorRunASAP) { bDontMoveMeIAmDoingShit = true; } // Still no target, let's see if we should backtrack or wait for wrath to come off cooldown... if (CurrentTarget == null) { RefreshDoBackTrack(); } // Still no target, let's end it all! if (CurrentTarget == null) { return(true); } // Ok record the time we last saw any unit at all if (CurrentTarget.Type == GObjectType.Unit) { lastHadUnitInSights = DateTime.Now; // And record when we last saw any form of elite if (CurrentTarget.IsBoss || CurrentTarget.IsEliteRareUnique || CurrentTarget.IsTreasureGoblin) { lastHadEliteUnitInSights = DateTime.Now; } } // Record the last time our target changed if (CurrentTargetRactorGUID != CurrentTarget.RActorGuid) { RecordTargetHistory(); DbHelper.Log(TrinityLogLevel.Verbose, LogCategory.Weight, "Found New Target - {0} CurrentTargetRactorGUID: {1} CurrentTarget.RActorGuid: {2}", DateTime.Now, CurrentTargetRactorGUID, CurrentTarget.RActorGuid); dateSincePickedTarget = DateTime.Now; iTargetLastHealth = 0f; } else { // We're sticking to the same target, so update the target's health cache to check for stucks if (CurrentTarget.Type == GObjectType.Unit) { // Check if the health has changed, if so update the target-pick time before we blacklist them again if (CurrentTarget.HitPointsPct != iTargetLastHealth) { DbHelper.Log(TrinityLogLevel.Verbose, LogCategory.Weight, "Keeping Target {0} - CurrentTarget.iHitPoints: {1:0.00} iTargetLastHealth: {2:0.00} ", CurrentTarget.RActorGuid, CurrentTarget.HitPointsPct, iTargetLastHealth); dateSincePickedTarget = DateTime.Now; } // Now store the target's last-known health iTargetLastHealth = CurrentTarget.HitPointsPct; } } } // We have a target and the cached was refreshed return(true); } }