internal static void ClearCache() { Logger.Write(LogLevel.Movement, "Clearing Skipahead Cache"); SkipAheadAreaCache.Clear(); UsedSkipAheadAreaCache.Clear(); lastRecordedSkipAheadCache = DateTime.Now; }
public CacheBalance(CacheItem item) { try { BalanceID = item.ref_DiaItem.CommonData.GameBalanceId; _itemLevel = item.ref_DiaItem.CommonData.Level; _type = item.ref_DiaItem.CommonData.ItemType; _base = item.ref_DiaItem.CommonData.ItemBaseType; _followerType = item.ref_DiaItem.CommonData.FollowerSpecialType; _pluginType = ItemFunc.DetermineItemType(item.InternalName, _type, _followerType, item.SNOID); if (item.ItemDropType.HasValue) { _pluginBase = ItemFunc.DetermineBaseItemType(item.ItemDropType.Value); } else { _pluginBase = ItemFunc.DetermineBaseItemType(item.InternalName, item.SNOID); } _isStackable = ItemFunc.DetermineIsStackable(_pluginType, item.SNOID); if (!_isStackable) { _isTwoSlot = ItemFunc.DetermineIsTwoSlot(_pluginType); } } catch (Exception ex) { Logger.Write(LogLevel.Items, String.Format("Failed to create balance data for item {0}", item.DebugStringSimple)); } }
public void Refresh(QuestInfo questinfo) { int curStep = Step; try { State = questinfo.State; Step = questinfo.QuestStep; KillCount = questinfo.KillCount; QuestMeter = questinfo.QuestMeter; BonusCount = questinfo.BonusCount; CreationTick = questinfo.CreationTick; if (curStep != Step) { Logger.Write(LogLevel.Bounty, "Active Quest {2} Step Changed From {0} To {1}", curStep, Step, QuestSNO); QuestStepChanged(QuestSNO, curStep, Step); } } catch (Exception ex) { Logger.Write(LogLevel.Bounty, "Safely handled updating quest info (qi) cache for entry {0}\r\n" + "Ex: {1}\r\n{2}", QuestSNO, ex.Message, ex.StackTrace); } }
public override bool IsStillValid() { if (ref_DiaItem == null || !ref_DiaItem.IsValid || ref_DiaItem.BaseAddress == IntPtr.Zero) { Logger.Write(LogLevel.Cache, "Reference DiaItem not valid for {0}", DebugStringSimple); _IsStillValid = false; return(false); } if (ref_DiaItem.CommonData == null) { Logger.Write(LogLevel.Cache, "Reference DiaItem -- CommonData is null {0}", DebugStringSimple); _IsStillValid = false; return(false); } if (!ref_DiaItem.CommonData.IsValid) { Logger.Write(LogLevel.Cache, "Reference DiaItem -- CommonData not valid for {0}", DebugStringSimple); _IsStillValid = false; return(false); } if (ref_DiaItem.CommonData.ACDGuid == -1) { Logger.Write(LogLevel.Cache, "Reference DiaItem -- CommonData ACDGuid is -1 {0}", DebugStringSimple); _IsStillValid = false; return(false); } return(base.IsStillValid()); }
public override void Refresh() { int curStep = Step; try { using (ZetaDia.Memory.AcquireFrame()) { foreach (var quest in ZetaDia.ActInfo.ActiveQuests) { if (quest.QuestSNO == QuestSNO) { Step = quest.QuestStep; State = quest.State; KillCount = quest.KillCount; QuestMeter = quest.QuestMeter; BonusCount = quest.BonusCount; CreationTick = quest.CreationTick; if (curStep != Step) { Logger.Write(LogLevel.Bounty, "Active Quest {2} Step Changed From {0} To {1}", curStep, Step, QuestSNO); QuestStepChanged(QuestSNO, curStep, Step); } return; } } } } catch (Exception ex) { Logger.Write(LogLevel.Bounty, "Safely hanlded updating quest info cache for entry {0}\r\n" + "Ex: {1}\r\n{2}", QuestSNO, ex.Message, ex.StackTrace); } }
internal static void InitTPBehavior() { Logger.Write(LogLevel.OutOfCombat, "Starting TP Behavior", true); worldtransferStarted = false; worldChanged = false; //GameEvents.OnWorldChanged+=OnWorldChanged; //GameEvents.OnWorldTransferStart+=OnWorldChangeStart; initizedTPBehavior = true; StartingPosition = FunkyGame.Hero.Position; MovementOccured = false; }
internal void UpdateRotation() { using (ZetaDia.Memory.AcquireFrame()) { try { Rotation = ref_DiaObject.Movement.Rotation; } catch (Exception) { Logger.Write(LogLevel.Cache, "Safely Handled Updating Rotation for Object {0}", InternalName); } } }
public virtual void UpdatePosition(bool force = false) { if (!force || (UnitPropertyFlags.HasValue && ObjectCache.CheckFlag(UnitPropertyFlags.Value, UnitFlags.Stationary))) { double lastUpdated = DateTime.Now.Subtract(lastUpdatedPosition).TotalMilliseconds; if (UnitPropertyFlags.HasValue && ObjectCache.CheckFlag(UnitPropertyFlags.Value, UnitFlags.Stationary) && lastUpdated < 100000) { return; } if (lastUpdated < 150) { return; } } using (ZetaDia.Memory.AcquireFrame()) { try { Position = ref_DiaObject.Position; } catch { Logger.Write(LogLevel.Cache, "Safely Handled Updating Position for Object {0}", InternalName); } lastUpdatedPosition = DateTime.Now; positionUpdated = true; } //Special Position Adjustment! if (UnitPropertyFlags.HasValue && ObjectCache.CheckFlag(UnitPropertyFlags.Value, UnitFlags.Stationary)) { UpdateRotation(); float distance = ActorSphereRadius.HasValue ? ActorSphereRadius.Value : CollisionRadius.HasValue ? CollisionRadius.Value : Radius; Vector3 curPosition = Position; Position = MathEx.GetPointAt(curPosition, distance, Rotation); } }
internal void OnGameIDChangedHandler() { Logger.Write(LogLevel.OutOfCombat, "New Game Started"); if (FunkyGame.AdventureMode) { ResetCombatModifiers(); } //Clear Interactable Cache ObjectCache.InteractableObjectCache.Clear(); //Clear Health Average ObjectCache.Objects.ClearHealthAverageStats(); //Renew bot FunkyGame.ResetBot(); }
internal static bool CanCastTP() { string TPcastTest; bool cancast; try { cancast = ZetaDia.Me.CanUseTownPortal(out TPcastTest); } catch (NullReferenceException) { TPcastTest = "Exception during CanUseTownPortal"; cancast = false; } if (!cancast) { Logger.Write(LogLevel.OutOfCombat, "Cannot cast TP: " + TPcastTest); return(false); } return(true); }
internal void OnTargetChanged(TargetChangedArgs e) { Logger.Write(LogLevel.Target, "Changed Object: {0}", MakeStringSingleLine(e.newObject.DebugString)); LastChangeOfTarget = DateTime.Now; FleeingLastTarget = false; AvoidanceLastTarget = false; CurrentUnitTarget = null; FunkyGame.Hero.Class.PowerPrime = FunkyGame.Hero.Class.DefaultAttack; if (CurrentTarget.targetType == TargetType.Container && FunkyBaseExtension.Settings.General.EnableWaitAfterContainers) { //Herbfunks delay for container loot. lastHadContainerAsTarget = DateTime.Now; if (CurrentTarget.IsResplendantChest) { lastHadRareChestAsTarget = DateTime.Now; } } else if (CurrentTarget.targetType == TargetType.Unit) { CurrentUnitTarget = (CacheUnit)CurrentTarget; //Used to pause after no targets found. lastHadUnitInSights = DateTime.Now; // And record when we last saw any form of elite if (CurrentUnitTarget.IsBoss || CurrentUnitTarget.IsEliteRareUnique || CurrentUnitTarget.IsTreasureGoblin) { lastHadEliteUnitInSights = DateTime.Now; } } else if (CurrentTarget.targetType == TargetType.Avoidance) { LastAvoidanceMovement = DateTime.Now; AvoidanceLastTarget = true; } else if (CurrentTarget.targetType.Value == TargetType.Fleeing) { LastFleeAction = DateTime.Now; FleeingLastTarget = true; } else if (CurrentTarget.targetType.Value == TargetType.Item) { //Reset Item Vars FunkyGame.Targeting.Cache.recheckCount = 0; FunkyGame.Targeting.Cache.reCheckedFinished = false; FunkyGame.Targeting.Cache.CheckItemLootStackCount = 0; FunkyGame.Targeting.Cache.ShouldCheckItemLooted = false; } bWholeNewTarget = true; bPickNewAbilities = true; TargetChangeHandler handler = TargetChanged; if (handler != null) { handler(this, e); } }
private void RefreshBountyLevelChange() { //Logger.DBLog.InfoFormat("Updating Bounty Info!"); //Do we have any bounties stored?.. if we do refresh states if (CurrentBounties.Count == 0) { RefreshBountyInfo(); } else { RefreshBountyQuestStates(); } //If we are in town.. we don't do anything else! (Since the Active Bounty is no longer visible) if (FunkyGame.Hero.bIsInTown) { //We could check that active bounty has been completed.. if (ActiveBounty != null && BountyQuestStates.ContainsKey(ActiveBounty.QuestSNO) && BountyQuestStates[ActiveBounty.QuestSNO] == QuestState.Completed) { Logger.Write(LogLevel.Bounty, "ActiveBounty Quest State is Completed!"); ActiveBounty = null; } return; } //Do we have an active bounty set.. lets try to invalidate it. if (ActiveBounty == null) { UpdateActiveBounty(); } else if (!BountyQuestStates.ContainsKey(ActiveBounty.QuestSNO)) { Logger.Write(LogLevel.Bounty, "ActiveBounty is not contained within BountyQuestStates Cache!"); UpdateActiveBounty(); } else if (BountyQuestStates[ActiveBounty.QuestSNO] == QuestState.Completed) { Logger.Write(LogLevel.Bounty, "ActiveBounty Quest State is Completed!"); ActiveBounty = null; UpdateActiveBounty(); } //Refresh any Map Markers we could use for navigation.. RefreshBountyMapMarkers(); //Is ActiveBounty valid still? if (ActiveBounty != null) { //Load Act Bounty Cache if (!ZetaDia.IsInTown && ActiveBounty.Act != CurrentAct) { CurrentAct = ActiveBounty.Act; } if (CurrentBountyCacheEntry == null) { //Attempt to Match a Cache Entry to the QuestSNO. if (lastCheckedQuestSNO != ActiveBounty.QuestSNO) { //Only attempt search once for the SNO.. lastCheckedQuestSNO = ActiveBounty.QuestSNO; //var allCacheBounties = CurrentActCache.AllBounties; BountyDataCollection.BountyActCollection bountyActCache = null; switch (CurrentAct) { case Act.A1: bountyActCache = TheCache.ObjectIDCache.BountyEntries.ActOne; break; case Act.A2: bountyActCache = TheCache.ObjectIDCache.BountyEntries.ActTwo; break; case Act.A3: bountyActCache = TheCache.ObjectIDCache.BountyEntries.ActThree; break; case Act.A4: bountyActCache = TheCache.ObjectIDCache.BountyEntries.ActFour; break; case Act.A5: bountyActCache = TheCache.ObjectIDCache.BountyEntries.ActFive; break; } if (bountyActCache == null) { return; } foreach (var b in bountyActCache.AllBounties.Where(c => c.QuestSNOs != null && c.QuestSNOs.Any(i => i == ActiveBounty.QuestSNO))) { CurrentBountyCacheEntry = b; break; } } } } }
///<summary> ///Sets Active Bounty ///</summary> public void UpdateActiveBounty() { var activeBounty = new BountyInfoCache(); BountyInfo ZetaActiveBounty = null; using (ZetaDia.Memory.AcquireFrame()) { ZetaActiveBounty = ZetaDia.ActInfo.ActiveBounty; } if (ZetaActiveBounty != null) { activeBounty = new BountyInfoCache(ZetaDia.ActInfo.ActiveBounty); if ((ActiveBounty == null || ActiveBounty.QuestSNO != activeBounty.QuestSNO) && activeBounty.QuestSNO != 0) { ActiveBounty = activeBounty; Logger.Write(LogLevel.Bounty, "Active Bounty Changed To {0}", ActiveBounty.QuestSNO); //nullify Cache Entry then set it if Cache contains it. CurrentBountyCacheEntry = null; } else if (activeBounty.QuestSNO == 0) { //nullify when active bounty is nothing ActiveBounty = null; } return; } RefreshActiveQuests(); if (ActiveQuests.ContainsKey(ADVENTUREMODE_RIFTID) && ActiveQuests[ADVENTUREMODE_RIFTID].State != QuestState.NotStarted) { if (ActiveBounty != null && ActiveBounty.QuestSNO == ADVENTUREMODE_RIFTID) { ((QuestInfoCache)ActiveBounty).Refresh(); } else { ActiveBounty = ActiveQuests[ADVENTUREMODE_RIFTID]; Logger.Write(LogLevel.Bounty, "Active Bounty Changed To Rifting"); } } else if (ActiveQuests.ContainsKey(ADVENTUREMODE_GREATERRIFT_TRIAL) && ActiveQuests[ADVENTUREMODE_GREATERRIFT_TRIAL].State != QuestState.NotStarted) { if (ActiveBounty != null && ActiveBounty.QuestSNO == ADVENTUREMODE_GREATERRIFT_TRIAL) { ((QuestInfoCache)ActiveBounty).Refresh(); } else { ActiveBounty = ActiveQuests[ADVENTUREMODE_GREATERRIFT_TRIAL]; Logger.Write(LogLevel.Bounty, "Active Bounty Changed To Rift Trial"); } } else { Logger.Write(LogLevel.Bounty, "Active Bounty Is Null!"); } }
public override void Initialize() { base.Test = (ref CacheObject obj) => { if (obj == null) { // See if we should wait for milliseconds for possible loot drops before continuing run if (DateTime.Now.Subtract(FunkyGame.Targeting.Cache.lastHadUnitInSights).TotalMilliseconds <= FunkyBaseExtension.Settings.General.AfterCombatDelay && DateTime.Now.Subtract(FunkyGame.Targeting.Cache.lastHadEliteUnitInSights).TotalMilliseconds <= 10000 || //Cut the delay time in half for non-elite monsters! DateTime.Now.Subtract(FunkyGame.Targeting.Cache.lastHadUnitInSights).TotalMilliseconds <= FunkyBaseExtension.Settings.General.AfterCombatDelay) { obj = new CacheObject(FunkyGame.Hero.Position, TargetType.NoMovement, 20000, "WaitForLootDrops", 2f, -1); return(true); } //Herbfunks wait after loot containers are opened. 3s for rare chests, half the settings delay for everything else. if ((DateTime.Now.Subtract(FunkyGame.Targeting.Cache.lastHadRareChestAsTarget).TotalMilliseconds <= 3750) || (DateTime.Now.Subtract(FunkyGame.Targeting.Cache.lastHadContainerAsTarget).TotalMilliseconds <= (FunkyBaseExtension.Settings.General.AfterCombatDelay * 1.25))) { obj = new CacheObject(FunkyGame.Hero.Position, TargetType.NoMovement, 20000, "ContainerLootDropsWait", 2f, -1); return(true); } if (DateTime.Now.Subtract(FunkyGame.Targeting.Cache.lastSeenCursedShrine).TotalMilliseconds <= (1000)) { if (FunkyGame.AdventureMode && SettingAdventureMode.AdventureModeSettingsTag.AllowCombatModifications && FunkyGame.Bounty.CurrentBountyCacheEntry != null && FunkyGame.Bounty.CurrentBountyCacheEntry.Type == BountyTypes.CursedEvent) { Logger.DBLog.Info("[Funky] Cursed Object Found During Cursed Bounty -- Enabling LOS movement for all Units!"); SettingLOSMovement.LOSSettingsTag.MiniumRangeObjects = 10; SettingLOSMovement.LOSSettingsTag.MaximumRange = 125; FunkyGame.Game.AllowAnyUnitForLOSMovement = true; SettingCluster.ClusterSettingsTag = SettingCluster.DisabledClustering; } obj = new CacheObject(FunkyGame.Hero.Position, TargetType.NoMovement, 20000, "CursedShrineWait", 2f, -1); return(true); } if (DateTime.Now.Subtract(FunkyGame.Targeting.Cache.lastHadSwitchAsTarget).TotalMilliseconds <= (4000)) { obj = new CacheObject(FunkyGame.Hero.Position, TargetType.NoMovement, 20000, "SwitchWait", 2f, -1); return(true); } // Finally, a special check for waiting for wrath of the berserker cooldown before engaging Azmodan if (Hotbar.HasPower(SNOPower.Barbarian_WrathOfTheBerserker) && FunkyBaseExtension.Settings.Barbarian.bWaitForWrath && !FunkyGame.Hero.Class.Abilities[SNOPower.Barbarian_WrathOfTheBerserker].AbilityUseTimer() && FunkyGame.Hero.CurrentWorldDynamicID == 121214 && (Vector3.Distance(FunkyGame.Hero.Position, new Vector3(711.25f, 716.25f, 80.13903f)) <= 40f || Vector3.Distance(FunkyGame.Hero.Position, new Vector3(546.8467f, 551.7733f, 1.576313f)) <= 40f)) { Logger.DBLog.InfoFormat("[Funky] Waiting for Wrath Of The Berserker cooldown before continuing to Azmodan."); obj = new CacheObject(FunkyGame.Hero.Position, TargetType.NoMovement, 20000, "GilesWaitForWrath", 0f, -1); InactivityDetector.Reset(); return(true); } // And a special check for wizard archon if (Hotbar.HasPower(SNOPower.Wizard_Archon) && !FunkyGame.Hero.Class.Abilities[SNOPower.Wizard_Archon].AbilityUseTimer() && FunkyBaseExtension.Settings.Wizard.bWaitForArchon && ZetaDia.CurrentWorldId == 121214 && (Vector3.Distance(FunkyGame.Hero.Position, new Vector3(711.25f, 716.25f, 80.13903f)) <= 40f || Vector3.Distance(FunkyGame.Hero.Position, new Vector3(546.8467f, 551.7733f, 1.576313f)) <= 40f)) { Logger.DBLog.InfoFormat("[Funky] Waiting for Wizard Archon cooldown before continuing to Azmodan."); obj = new CacheObject(FunkyGame.Hero.Position, TargetType.NoMovement, 20000, "GilesWaitForArchon", 0f, -1); InactivityDetector.Reset(); return(true); } // And a very sexy special check for WD BigBadVoodoo if (Hotbar.HasPower(SNOPower.Witchdoctor_BigBadVoodoo) && !PowerManager.CanCast(SNOPower.Witchdoctor_BigBadVoodoo) && ZetaDia.CurrentWorldId == 121214 && (Vector3.Distance(FunkyGame.Hero.Position, new Vector3(711.25f, 716.25f, 80.13903f)) <= 40f || Vector3.Distance(FunkyGame.Hero.Position, new Vector3(546.8467f, 551.7733f, 1.576313f)) <= 40f)) { Logger.DBLog.InfoFormat("[Funky] Waiting for WD BigBadVoodoo cooldown before continuing to Azmodan."); obj = new CacheObject(FunkyGame.Hero.Position, TargetType.NoMovement, 20000, "GilesWaitForVoodooo", 0f, -1); InactivityDetector.Reset(); return(true); } //Currently preforming an interactive profile behavior (check if in town and not vendoring) if (FunkyGame.Game.InteractableCachedObject != null && (!FunkyGame.Hero.bIsInTown || !BrainBehavior.IsVendoring)) { if (FunkyGame.Game.InteractableCachedObject.Position.Distance(FunkyGame.Hero.Position) > 50f) { //if (FunkyGame.Targeting.Cache.LastCachedTarget.Position != Bot.Game.Profile.InteractableCachedObject.Position) // Navigator.Clear(); //Generate the path here so we can start moving.. Navigation.Navigation.NP.MoveTo(FunkyGame.Game.InteractableCachedObject.Position, "ReturnToOOCLoc", true); //Setup a temp target that the handler will use obj = new CacheObject(FunkyGame.Game.InteractableCachedObject.Position, TargetType.LineOfSight, 1d, "ReturnToOOCLoc", 10f, FunkyGame.Game.InteractableCachedObject.RAGUID); return(true); } } //Check if we engaged in combat.. bool EngagedInCombat = false; float distanceFromStart = 0f; if (!FunkyGame.Targeting.Cache.LastCachedTarget.Equals(ObjectCache.FakeCacheObject) && !FunkyGame.Targeting.Cache.Backtracking && FunkyGame.Targeting.Cache.StartingLocation != Vector3.Zero) { EngagedInCombat = true; distanceFromStart = FunkyGame.Hero.Position.Distance(FunkyGame.Targeting.Cache.StartingLocation); //lets see how far we are from our starting location. if (distanceFromStart > 20f && !Navigation.Navigation.CanRayCast(FunkyGame.Hero.Position, PlayerMover.vLastMoveTo, UseSearchGridProvider: true)) { Logger.Write(LogLevel.Movement, "Updating Navigator in Target Refresh"); SkipAheadCache.ClearCache(); Navigator.Clear(); //Navigator.MoveTo(Funky.PlayerMover.vLastMoveTo, "original destination", true); } } //Check if our current path intersects avoidances. (When not in town, and not currently inside avoidance) if (!FunkyGame.Hero.bIsInTown && (FunkyBaseExtension.Settings.Avoidance.AttemptAvoidanceMovements) && //|| FunkyGame.Hero.CriticalAvoidance) Navigation.Navigation.NP.CurrentPath.Count > 0 && FunkyGame.Targeting.Cache.Environment.TriggeringAvoidances.Count == 0) { if (ObjectCache.Obstacles.TestVectorAgainstAvoidanceZones(FunkyGame.Hero.Position, Navigation.Navigation.NP.CurrentPath.Current)) { obj = new CacheObject(FunkyGame.Hero.Position, TargetType.NoMovement, 20000, "AvoidanceIntersection", 2.5f, -1); return(true); } } //Backtracking Check.. if (EngagedInCombat && FunkyBaseExtension.Settings.Backtracking.EnableBacktracking && distanceFromStart >= FunkyBaseExtension.Settings.Backtracking.MinimumDistanceFromStart) { FunkyGame.Targeting.Cache.Backtracking = true; obj = new CacheObject(FunkyGame.Targeting.Cache.StartingLocation, TargetType.Backtrack, 20000, "Backtracking", 2.5f); return(true); } } return(obj != null); }; }
///<summary> ///Iterates through Usable objects and sets the Bot.CurrentTarget to the highest weighted object found inside the given list. ///</summary> private void WeightEvaluationObjList(ref CacheObject CurrentTarget) { //clear our last "avoid" list.. FunkyGame.Targeting.Cache.objectsIgnoredDueToAvoidance.Clear(); double iHighestWeightFound = 0; foreach (CacheObject thisobj in FunkyGame.Targeting.Cache.ValidObjects) { thisobj.UpdateWeight(); if (thisobj.Weight == 1) { // Force the character to stay where it is if there is nothing available that is out of avoidance stuff and we aren't already in avoidance stuff thisobj.Weight = 0; if (!FunkyGame.Targeting.Cache.RequiresAvoidance) { bStayPutDuringAvoidance = true; } continue; } // Is the weight of this one higher than the current-highest weight? Then make this the new primary target! if (thisobj.Weight > iHighestWeightFound && thisobj.Weight > 0) { //Check combat looting (Demonbuddy Setting) if (iHighestWeightFound > 0 && (thisobj.targetType.HasValue && (thisobj.targetType.Value == TargetType.Item || thisobj.targetType.Value == TargetType.Gold)) && !CharacterSettings.Instance.CombatLooting && (CurrentTarget.targetType.HasValue && CurrentTarget.targetType.Value == TargetType.Unit)) { continue; } if (thisobj.targetType.HasValue && thisobj.targetType.Value == TargetType.Unit) { Skill nextAbility = FunkyGame.Hero.Class.AbilitySelector((CacheUnit)thisobj, FunkyGame.Targeting.Cache.Environment.TriggeringAvoidances.Count > 0); if (nextAbility.Equals(FunkyGame.Hero.Class.DefaultAttack) && !FunkyGame.Hero.Class.CanUseDefaultAttack) { //No valid ability found Logger.Write(LogLevel.Target, "Could not find a valid ability for unit {0}", thisobj.InternalName); continue; } //Should we check avoidances? if (FunkyGame.Targeting.Cache.Environment.NearbyAvoidances.Count > 0) { Vector3 destination = nextAbility.DestinationVector; if (destination.Equals(Vector3.Zero)) { continue; } if (ObjectCache.Obstacles.TestVectorAgainstAvoidanceZones(FunkyGame.Hero.Position, destination)) { FunkyGame.Targeting.Cache.objectsIgnoredDueToAvoidance.Add(thisobj); } } } //Avoidance Attempt to find a location where we can attack! if (FunkyGame.Targeting.Cache.objectsIgnoredDueToAvoidance.Contains(thisobj)) { //Wait if no valid target found yet.. and no avoidance movement required. if (!FunkyGame.Targeting.Cache.RequiresAvoidance) { bStayPutDuringAvoidance = true; } continue; } //Set our current target to this object! CurrentTarget = ObjectCache.Objects[thisobj.RAGUID]; iHighestWeightFound = thisobj.Weight; } } // Loop through all the objects and give them a weight }
public override void Initialize() { base.Test = (ref CacheObject obj) => { if (fBaseXtensions.FunkyBaseExtension.Settings.Logging.LogFlags.HasFlag(LogLevel.Movement)) { string avoidances = ""; FunkyGame.Targeting.Cache.Environment.TriggeringAvoidances.ForEach(a => avoidances = avoidances + a.AvoidanceType.ToString() + ", "); Logger.Write(LogLevel.Movement, "Avoidances Triggering: {0}", avoidances); } //Reuse the last generated safe spot... if (DateTime.Now.Subtract(FunkyGame.Targeting.Cache.LastAvoidanceMovement).TotalSeconds < this.iSecondsAvoidMoveFor) { Vector3 reuseV3 = FunkyGame.Navigation.AttemptToReuseLastLocationFound(); if (reuseV3 != Vector3.Zero) { if (!ObjectCache.Obstacles.IsPositionWithinAvoidanceArea(reuseV3)) { obj = new CacheObject(reuseV3, TargetType.Avoidance, 20000f, "SafeReuseAvoid", 2.5f, reuseV3.GetHashCode()); return(true); } } } Vector3 vAnySafePoint; //Check if we have any movement abilities we can cast.. if so lets not check avoidance intersections. PointCheckingFlags flags = FunkyBaseExtension.Settings.Plugin.AvoidanceFlags; if (FunkyGame.Hero.Class.HasCastableMovementAbility()) { flags &= ~(PointCheckingFlags.AvoidanceIntersection | PointCheckingFlags.BlockedDirection); } Vector3 losVector3 = Vector3.Zero; if (FunkyGame.Targeting.Cache.LastCachedTarget.targetType != null && FunkyGame.Targeting.Cache.LastCachedTarget.targetType.Value == TargetType.Unit) { losVector3 = FunkyGame.Targeting.Cache.LastCachedTarget.Position; } if (FunkyGame.Navigation.AttemptFindSafeSpot(out vAnySafePoint, losVector3, flags)) { float distance = vAnySafePoint.Distance(FunkyGame.Hero.Position); Logger.DBLog.DebugFormat("Avoid Movement found AT {0} with {1} Distance", vAnySafePoint.ToString(), distance); //setup avoidance target obj = new CacheObject(vAnySafePoint, TargetType.Avoidance, 20000f, "SafeAvoid", 2.5f, vAnySafePoint.GetHashCode()); //Estimate time we will be reusing this movement vector3 this.iSecondsAvoidMoveFor = 1 + (int)(distance / 5f); return(true); } else { //Failed to find any location.. //Set the future date we must wait for to retry.. AvoidRetryDate = DateTime.Now.AddMilliseconds(FunkyBaseExtension.Settings.Avoidance.FailureRetryMilliseconds); } return(false); }; }
public override bool UpdateData() { if (ref_DiaItem == null) { try { ref_DiaItem = (DiaItem)ref_DiaObject; } catch { Logger.Write(LogLevel.Cache, "Failure to convert obj {0} to DiaItem!", InternalName); NeedsRemoved = true; BlacklistFlag = BlacklistType.Temporary; return(false); } } bool skippingCommonDataUpdates = false; //Check if item is not a misc item (requires common data) if (ItemDropType.HasValue) { var baseItemType = ItemFunc.DetermineBaseItemType(ItemDropType.Value); var isstackable = ItemFunc.DetermineIsStackable(ItemDropType.Value); IsTwoSlot = ItemFunc.DetermineIsTwoSlot(ItemDropType.Value); skippingCommonDataUpdates = (baseItemType == PluginBaseItemTypes.Misc || baseItemType == PluginBaseItemTypes.Gem || baseItemType == PluginBaseItemTypes.HealthGlobe || (FunkyBaseExtension.Settings.Loot.PickupWhiteItems == 1 && FunkyBaseExtension.Settings.Loot.PickupMagicItems == 1 && FunkyBaseExtension.Settings.Loot.PickupRareItems == 1 && FunkyBaseExtension.Settings.Loot.PickupLegendaryItems == 1)); if (!skippingCommonDataUpdates) { if (!IsStillValid()) { NeedsRemoved = true; return(false); } } } else if (!IsStillValid()) { NeedsRemoved = true; return(false); } if (targetType.Value == TargetType.Item) { #region Item //#region DynamicID //if (!DynamicID.HasValue) //{ // try // { // DynamicID = ref_DiaItem.CommonData.DynamicId; // } // catch // { // Logger.Write(LogLevel.Cache, "Failure to get Dynamic ID for {0}", InternalName); // return false; // } //} //#endregion //Gamebalance Update if (!skippingCommonDataUpdates && !BalanceID.HasValue) { try { BalanceID = ref_DiaItem.CommonData.GameBalanceId; } catch { Logger.Write(LogLevel.Cache, "Failure to get gamebalance ID for item {0}", InternalName); return(false); } } //Check if game balance needs updated #region GameBalance if (!skippingCommonDataUpdates && (BalanceData == null || BalanceData.bNeedsUpdated)) { CacheBalance thisnewGamebalance; try { thisnewGamebalance = new CacheBalance(this); } catch { Logger.Write(LogLevel.Cache, "Failure to add/update gamebalance data for item {0}", InternalName); NeedsRemoved = true; return(false); } if (BalanceData == null) { CacheIDLookup.dictGameBalanceCache.Add(BalanceID.Value, thisnewGamebalance); } else { CacheIDLookup.dictGameBalanceCache[BalanceID.Value] = thisnewGamebalance; } } #endregion //Item Quality / Recheck #region ItemQuality if (!skippingCommonDataUpdates && (!Itemquality.HasValue || ItemQualityRechecked == false)) { try { Itemquality = ref_DiaItem.CommonData.ItemQualityLevel; } catch { Logger.Write(LogLevel.Cache, "Failure to get item quality for {0}", InternalName); return(false); } if (!ItemQualityRechecked) { ItemQualityRechecked = true; } else { NeedsUpdate = false; } } #endregion //Pickup? // Now see if we actually want it #region PickupValidation if (!ShouldPickup.HasValue) { //Logger.DBLog.InfoFormat Dropped Items Here!! if (BalanceData != null && Itemquality.HasValue) { if (FunkyGame.CurrentStats != null) { FunkyGame.CurrentStats.CurrentProfile.LootTracker.DroppedItemLog(BalanceData.PluginType, Itemquality.Value); } } //Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.DroppedItemLog(this); FunkyGame.ItemPickupEval(this); NeedsUpdate = false; } else { NeedsUpdate = false; } #endregion #endregion } else if (targetType.Value == TargetType.Globe || targetType.Value == TargetType.PowerGlobe) { NeedsUpdate = false; } else { #region Gold //Get gold value.. if (!GoldAmount.HasValue) { try { GoldAmount = ref_DiaItem.CommonData.GetAttribute <int>(ActorAttributeType.Gold); } catch { //Logger.Write(LogLevel.Cache, "Failure to get gold amount for gold pile!"); return(false); } } FunkyGame.Hero.UpdateCoinage = true; NeedsUpdate = false; #endregion } return(true); }
public static RunStatus FunkyTPBehavior(object ret) { //Init if (!initizedTPBehavior) { InitTPBehavior(); return(RunStatus.Running); } double ElapsedTime = DateTime.Now.Subtract(FunkyTP_LastCastAttempt).TotalSeconds; //Check world transfer start if (worldtransferStarted) { if (ElapsedTime < 10 || worldChanged) { //Logger.Write(LogLevel.OutOfCombat,"Waiting for world change!"); if (!FunkyGame.Hero.bIsInTown) { return(RunStatus.Running); } Logger.Write(LogLevel.OutOfCombat, "Casting Behavior Finished, we are in town!", true); ResetTPBehavior(); //UpdateSearchGridProvider(true); return(RunStatus.Success); } if (ElapsedTime >= 10 && !FunkyGame.Hero.bIsInTown) { //Retry? worldtransferStarted = false; CastAttempted = false; Vector3 UnstuckPos; if (FunkyGame.Navigation.AttemptFindSafeSpot(out UnstuckPos, Vector3.Zero, FunkyBaseExtension.Settings.Plugin.AvoidanceFlags)) { Logger.Write(LogLevel.OutOfCombat, "Generated Unstuck Position at {0}", UnstuckPos.ToString()); ZetaDia.Me.UsePower(SNOPower.Walk, UnstuckPos, FunkyGame.Hero.CurrentWorldDynamicID); } } return(RunStatus.Running); } //Precheck - Ingame, not dead.. if (!TPActionIsValid()) { ResetTPBehavior(); return(RunStatus.Success); } if (ZetaDia.IsLoadingWorld) //Loading.. we just wait! { return(RunStatus.Running); } if (!CanCastTP()) //Not loading but is valid.. see if we can cast? { ResetTPBehavior(); return(RunStatus.Success); } //Set our flag which is used to setup the refreshing specific for this/similar behaviors. FunkyTPBehaviorFlag = true; //Handle Targeting.. if (FunkyGame.Targeting.CheckHandleTarget() == RunStatus.Running) { return(RunStatus.Running); } if (MovementOccured) { //Backtrack to orginal location... bool isMoving = false; try { isMoving = ZetaDia.Me.Movement.IsMoving; } catch (NullReferenceException) { } //Use simple checking of movement, with UsePower on our last location. if (!isMoving) { double DistanceFromStart = StartingPosition.Distance(FunkyGame.Hero.Position); if (DistanceFromStart > 15f && DistanceFromStart < 50f) { //Logger.DBLog.InfoFormat("[FunkyTP] Backtracking!"); //Move back to starting position.. //ZetaDia.Me.UsePower(SNOPower.Walk, StartingPosition); //return RunStatus.Running; } else if (DistanceFromStart >= 50f) { //Logger.DBLog.InfoFormat("[FunkyTP] Range from our starting position is {0}. Now using Navigator to move.", DistanceFromStart); //Navigator.MoveTo(StartingPosition, "Backtracking to Orginal Position", true); } } else { return(RunStatus.Running); } MovementOccured = false; } //Make sure we are not moving.. if (FunkyGame.Hero.IsMoving) { return(RunStatus.Running); } //Check if we are casting, if not cast, else if casting but time has elapsed then cancel cast. if (!CastingRecall()) { //Check last time cast.. if (ElapsedTime > 5 && CastAttempted) { worldtransferStarted = true; return(RunStatus.Running); } if (ElapsedTime > 8 || !CastAttempted) { //Recast Logger.Write(LogLevel.OutOfCombat, "Casting TP.."); ZetaDia.Me.UseTownPortal(); CastAttempted = true; FunkyTP_LastCastAttempt = DateTime.Now; } return(RunStatus.Running); } if (ElapsedTime > 8) { //Void Cast? Logger.Write(LogLevel.OutOfCombat, "Attempting to void cast with movement.."); Vector3 V3loc; bool success = FunkyGame.Navigation.AttemptFindSafeSpot(out V3loc, Vector3.Zero, FunkyBaseExtension.Settings.Plugin.AvoidanceFlags); if (success) { Navigator.MoveTo(V3loc, "Void Cast Movement", false); } return(RunStatus.Running); } return(RunStatus.Running); }
private void CheckActiveBounty() { if (FunkyGame.AdventureMode) { FunkyGame.Game.ResetCombatModifiers(); if (!FunkyGame.Bounty.IsInRiftWorld) { //We could check that active bounty has been completed.. if (FunkyGame.Bounty.ActiveBounty != null && FunkyGame.Bounty.BountyQuestStates.ContainsKey(FunkyGame.Bounty.ActiveBounty.QuestSNO) && FunkyGame.Bounty.BountyQuestStates[FunkyGame.Bounty.ActiveBounty.QuestSNO] == QuestState.Completed) { Logger.Write(Helpers.LogLevel.Bounty, "ActiveBounty Quest State is Completed!"); } if (FunkyGame.Bounty.CurrentBountyCacheEntry != null) { var CurrentBountyCacheEntry = FunkyGame.Bounty.CurrentBountyCacheEntry; Logger.Write(Helpers.LogLevel.Bounty, "Checking Bounty Type {0}", CurrentBountyCacheEntry.Type); int curLevelID = FunkyGame.Hero.iCurrentLevelID; //Check if We should Modify the Bots Combat Behavior switch (FunkyGame.Bounty.CurrentBountyCacheEntry.Type) { case BountyTypes.Clear: if (CurrentBountyCacheEntry.EndingLevelAreaID == curLevelID) { Logger.Write(Helpers.LogLevel.Bounty, "Bounty Level ID Match (Clear) -- Disabling Cluster Logic!"); if (FunkyBaseExtension.Settings.AdventureMode.AllowCombatModifications) { SettingCluster.ClusterSettingsTag = SettingCluster.DisabledClustering; SettingLOSMovement.LOSSettingsTag.MiniumRangeObjects = 5; FunkyGame.Game.AllowAnyUnitForLOSMovement = true; } } break; case BountyTypes.Kill: if (CurrentBountyCacheEntry.StartingLevelAreaID == curLevelID || CurrentBountyCacheEntry.EndingLevelAreaID == curLevelID || CurrentBountyCacheEntry.LevelAreaIDs != null && CurrentBountyCacheEntry.LevelAreaIDs.Any(i => i == curLevelID)) { Logger.Write(Helpers.LogLevel.Bounty, "Bounty Level ID Match (Kill) -- Disabling Cluster Logic and Enabling Navigation of Points!"); if (FunkyBaseExtension.Settings.AdventureMode.AllowCombatModifications) { SettingCluster.ClusterSettingsTag = SettingCluster.DisabledClustering; } if (FunkyBaseExtension.Settings.AdventureMode.NavigatePointsOfInterest) { FunkyGame.Game.ShouldNavigateMinimapPoints = CurrentBountyCacheEntry.EndingLevelAreaID == curLevelID; } } break; case BountyTypes.CursedEvent: if (CurrentBountyCacheEntry.EndingLevelAreaID == curLevelID) { Logger.Write(Helpers.LogLevel.Bounty, "Bounty Level ID Match (CursedEvent) -- Enabling Navigation of Points!"); if (FunkyBaseExtension.Settings.AdventureMode.NavigatePointsOfInterest) { FunkyGame.Game.ShouldNavigateMinimapPoints = true; } FunkyGame.Game.QuestMode = true; } break; case BountyTypes.Boss: if (CurrentBountyCacheEntry.StartingLevelAreaID == curLevelID) { Logger.Write(Helpers.LogLevel.Bounty, "Bounty Level ID Match (Boss) -- Enabling Navigation of Points!"); if (FunkyBaseExtension.Settings.AdventureMode.NavigatePointsOfInterest) { FunkyGame.Game.ShouldNavigateMinimapPoints = true; } } break; case BountyTypes.Event: if (CurrentBountyCacheEntry.EndingLevelAreaID == curLevelID) { Logger.Write(Helpers.LogLevel.Bounty, "Bounty Level ID Match (Event) -- Enabling Navigation of Points!"); if (FunkyBaseExtension.Settings.AdventureMode.NavigatePointsOfInterest) { FunkyGame.Game.ShouldNavigateMinimapPoints = true; } FunkyGame.Game.QuestMode = true; } break; } } } else if (FunkyGame.Bounty.ActiveBounty != null) { int curStep = ((BountyCache.QuestInfoCache)FunkyGame.Bounty.ActiveBounty).Step; //Killing.. if (curStep == 1 || curStep == 13) { if (curStep == 13) { MonitorSettings.MonitorSettingsTag.GoldInactivityTimeoutSeconds = 0; } if (FunkyBaseExtension.Settings.AdventureMode.NavigatePointsOfInterest) { FunkyGame.Bounty.RefreshRiftMapMarkers(); FunkyGame.Game.ShouldNavigateMinimapPoints = true; } if (FunkyBaseExtension.Settings.AdventureMode.AllowCombatModifications) { SettingCluster.ClusterSettingsTag = SettingCluster.DisabledClustering; } } else if (curStep == 3 || curStep == 16) //Boss Spawned { if (curStep == 16) { MonitorSettings.MonitorSettingsTag.GoldInactivityTimeoutSeconds = 0; } if (FunkyBaseExtension.Settings.AdventureMode.NavigatePointsOfInterest) { FunkyGame.Bounty.RefreshRiftMapMarkers(); FunkyGame.Game.ShouldNavigateMinimapPoints = false; } if (FunkyBaseExtension.Settings.AdventureMode.AllowCombatModifications) { SettingCluster.ClusterSettingsTag = FunkyBaseExtension.Settings.Cluster; } } else //Boss Killed 10 / 34 { if (curStep == 10 || curStep == 34) { MonitorSettings.MonitorSettingsTag.GoldInactivityTimeoutSeconds = 0; } //SettingCluster.ClusterSettingsTag = FunkyBaseExtension.Settings.Cluster; //FunkyGame.Game.ShouldNavigateMinimapPoints = false; } } } }
private void levelareaIDchanged(int ID) { iCurrentLevelID = ID; Logger.Write(Helpers.LogLevel.Event, "Level Area ID has Changed to {0}", ID); if (!BrainBehavior.IsVendoring) { //Check for World ID change! if (FunkyGame.Hero.CurrentWorldDynamicID != LastWorldID) { Logger.Write(Helpers.LogLevel.Event, "World ID changed.. clearing Profile Interactable Cache."); LastWorldID = FunkyGame.Hero.CurrentWorldDynamicID; ObjectCache.InteractableObjectCache.Clear(); //Gold Inactivity GoldInactivity.LastCoinageUpdate = DateTime.Now; } if (!LastLevelIDChangeWasTownRun) { //Do full clear BackTrackCache.cacheMovementGPRs.Clear(); FunkyGame.Navigation.LOSBlacklistedRAGUIDs.Clear(); FunkyGame.Game.InteractableCachedObject = null; } else { //Gold Inactivity GoldInactivity.LastCoinageUpdate = DateTime.Now; } //Clear the object cache! ObjectCache.Objects.Clear(); //ObjectCache.cacheSnoCollection.ClearDictionaryCacheEntries(); ObjectCache.RemovalCheck = false; //Every ten minutes clear perm RAGUID list BlacklistCache.CheckPermBlacklist(); ZetaDia.Actors.Clear(); ZetaDia.Actors.Update(); //Reset Skip Ahead Cache SkipAheadCache.ClearCache(); FunkyGame.Hero.UpdateCoinage = true; //Check active bounty if (FunkyGame.AdventureMode) { CheckActiveBounty(); } Navigator.SearchGridProvider.Update(); LastLevelIDChangeWasTownRun = false; } else if (FunkyGame.Hero.bIsInTown) { LastLevelIDChangeWasTownRun = true; } if (OnLevelAreaIDChanged != null) { OnLevelAreaIDChanged(ID); } }
// ///<summary> ///Adds/Updates CacheObjects inside collection by Iteration of RactorList ///This is the method that caches all live data about an object! ///</summary> internal static bool UpdateCacheObjectCollection() { //Update Character (just incase it wasnt called before..) FunkyGame.Hero.Update(false, true); Obstacles.AttemptToClearEntries(); HashSet <int> hashDoneThisRactor = new HashSet <int>(); using (ZetaDia.Memory.AcquireFrame(true)) { if (!ZetaDia.IsInGame || ZetaDia.IsLoadingWorld || !ZetaDia.Me.IsValid) { return(false); } foreach (Actor thisActor in ZetaDia.Actors.RActorList) { int tmp_raGUID; DiaObject thisObj; if (!thisActor.IsValid) { continue; } //Convert to DiaObject thisObj = (DiaObject)thisActor; tmp_raGUID = thisObj.RActorGuid; // See if we've already checked this ractor, this loop if (hashDoneThisRactor.Contains(tmp_raGUID)) { continue; } hashDoneThisRactor.Add(tmp_raGUID); //Update RactorGUID and check blacklisting.. if (BlacklistCache.IsRAGUIDBlacklisted(tmp_raGUID)) { continue; } CacheObject tmp_CachedObj; if (!Objects.TryGetValue(tmp_raGUID, out tmp_CachedObj)) { ActorType Actortype; Vector3 tmp_position; int tmp_acdguid; int tmp_SNOID; #region SNO //Lookup SNO try { tmp_SNOID = thisObj.ActorSNO; } catch (Exception ex) { Logger.Write(LogLevel.Cache, "Safely handled getting SNO for {0}", tmp_raGUID); //Logger.DBLog.InfoFormat("Failure to get SNO from object! RaGUID: {0}", tmp_raGUID); continue; } #endregion //check our SNO blacklist (exclude pets?) if (BlacklistCache.IsSNOIDBlacklisted(tmp_SNOID)) { continue; } #region Position try { tmp_position = thisObj.Position; } catch (Exception ex) { Logger.Write(LogLevel.Cache, "Safely handled getting Position for {0}", tmp_SNOID); continue; } #endregion #region AcdGUID try { tmp_acdguid = thisObj.ACDGuid; } catch (Exception ex) { Logger.Write(LogLevel.Cache, "Safely handled getting ACDGuid for {0}", tmp_SNOID); continue; } #endregion tmp_CachedObj = new CacheObject(tmp_SNOID, tmp_raGUID, tmp_acdguid, tmp_position); } else { //Reset unseen var tmp_CachedObj.LoopsUnseen = 0; } ////Validate (ignore special object SNO Ids) //if (!CacheIDLookup.hashSNOSkipCommonDataCheck.Contains(tmp_CachedObj.SNOID)) //{ // try // { // if (thisObj.CommonData == null) // { // Logger.Write(LogLevel.Cache, "CommonData is no longer valid! {0}", tmp_CachedObj.DebugStringSimple); // //BlacklistCache.AddObjectToBlacklist(tmp_CachedObj.RAGUID, BlacklistType.Temporary); // continue; // } // if (thisObj.CommonData.ACDGuid != thisObj.ACDGuid) // { // Logger.Write(LogLevel.Cache, "ACDGuid Mismatched! {0}", tmp_CachedObj.DebugStringSimple); // //BlacklistCache.AddObjectToBlacklist(tmp_CachedObj.RAGUID, BlacklistType.Temporary); // continue; // } // } // catch (Exception ex) // { // //Logger.Write(LogLevel.Cache, "Object is no longer valid! (Exception) SNOID {0}", tmp_CachedObj.DebugStringSimple); // //BlacklistCache.AddObjectToBlacklist(tmp_CachedObj.RAGUID, BlacklistType.Temporary); // continue; // } //} //Update any SNO Data. #region SNO_Cache_Update if (tmp_CachedObj.ref_DiaObject == null || tmp_CachedObj.ContainsNullValues()) { if (!tmp_CachedObj.UpdateData(thisObj, tmp_CachedObj.RAGUID)) { continue; } } else if (!tmp_CachedObj.IsFinalized) { //Finalize this data by recreating it and updating the Sno cache with a new finalized entry, this also clears our all Sno cache dictionaries since we no longer need them! cacheSnoCollection.FinalizeEntry(tmp_CachedObj.SNOID); } #endregion //Check if this object is a summoned unit by a player... #region SummonedUnits if (tmp_CachedObj.IsSummonedPet && CacheIDLookup.hashSNOSkipCommonDataCheck.Contains(tmp_CachedObj.SNOID)) { PetTypes PetType = (PetTypes)TheCache.ObjectIDCache.UnitPetEntries[tmp_CachedObj.SNOID].ObjectType; if (PetType == PetTypes.WIZARD_ArcaneOrbs) { FunkyGame.Targeting.Cache.Environment.HeroPets.WizardArcaneOrbs++; tmp_CachedObj.NeedsRemoved = true; continue; } } #endregion //Special Cache for Interactable Server Objects if (CheckFlag(tmp_CachedObj.targetType.Value, TargetType.ServerInteractable)) { if (!InteractableObjectCache.ContainsKey(tmp_CachedObj.RAGUID)) { InteractableObjectCache.Add(tmp_CachedObj.RAGUID, tmp_CachedObj); //Adventure Mode -- Rifting we add Exit to LOS movement! //if (FunkyGame.AdventureMode && FunkyGame.Bounty.IsInRiftWorld && FunkyBaseExtension.Settings.AdventureMode.EnableAdventuringMode) //{ // if (tmp_CachedObj.InternalName.Contains("Exit")) // { // int index = FunkyGame.Bounty.CurrentBountyMapMarkers.Count; // FunkyGame.Bounty.CurrentBountyMapMarkers.Add(index, new BountyCache.BountyMapMarker(tmp_CachedObj.Position, FunkyGame.Hero.CurrentWorldDynamicID, index)); // } //} } //Whymsdal Portal! if (tmp_CachedObj.SNOID == 405590) { GoblinBehavior.Portal = tmp_CachedObj; } else if (tmp_CachedObj.SNOID == 393030) { GoblinBehavior.Portal = tmp_CachedObj; } //Do not add to main cache! continue; } //Objects with static positions already cached don't need to be updated here. if (!tmp_CachedObj.NeedsUpdate) { continue; } //Obstacles -- (Not an actual object we add to targeting.) if (CheckFlag(tmp_CachedObj.targetType.Value, TargetType.Avoidance) || tmp_CachedObj.IsObstacle || tmp_CachedObj.HandleAsAvoidanceObject) { #region Obstacles CacheObstacle thisObstacle; //Do we have this cached? if (!Obstacles.TryGetValue(tmp_CachedObj.RAGUID, out thisObstacle)) { AvoidanceType AvoidanceType = AvoidanceType.None; if (tmp_CachedObj.IsAvoidance) { AvoidanceType = AvoidanceCache.FindAvoidanceUsingSNOID(tmp_CachedObj.SNOID); if (AvoidanceType == AvoidanceType.None) { AvoidanceType = AvoidanceCache.FindAvoidanceUsingName(tmp_CachedObj.InternalName); if (AvoidanceType == AvoidanceType.None) { continue; } } } if (tmp_CachedObj.IsAvoidance && tmp_CachedObj.IsProjectileAvoidance) { //Ranged Projectiles require more than simple bounding points.. so we create it as avoidance zone to cache it with properties. //Check for intersection.. try { ActorMovement thisMovement = thisObj.Movement; Vector2 Direction = thisMovement.DirectionVector; Ray R = new Ray(tmp_CachedObj.Position, Direction.ToVector3()); double Speed; //Lookup Cached Speed, or add new entry. if (!dictProjectileSpeed.TryGetValue(tmp_CachedObj.SNOID, out Speed)) { Speed = thisMovement.DesiredSpeed; dictProjectileSpeed.Add(tmp_CachedObj.SNOID, Speed); } thisObstacle = new CacheAvoidance(tmp_CachedObj, AvoidanceType, R, Speed); Obstacles.Add(thisObstacle); } catch { Logger.Write(LogLevel.Cache, "Failed to create projectile avoidance with rotation and speed. {0}", tmp_CachedObj.InternalName); } } else if (tmp_CachedObj.IsAvoidance) { //Poison Gas Can Be Friendly... if (AvoidanceType == AvoidanceType.PoisonGas) { int TeamID = 0; try { TeamID = thisObj.CommonData.GetAttribute <int>(ActorAttributeType.TeamID); } catch { Logger.Write(LogLevel.Cache, "Failed to retrieve TeamID attribute for object {0}", tmp_CachedObj.InternalName); } //ID of 1 means its non-hostile! (-1?) 2?? //if (TeamID==1||TeamID==-1) if (TeamID != 10) { //Logger.Write(LogLevel.None, "Ignoring Avoidance {0} due to Friendly TeamID match!", tmp_CachedObj.InternalName); BlacklistCache.AddObjectToBlacklist(tmp_CachedObj.RAGUID, BlacklistType.Permanent); continue; } } thisObstacle = new CacheAvoidance(tmp_CachedObj, AvoidanceType); Obstacles.Add(thisObstacle); } else { //Obstacles. thisObstacle = new CacheServerObject(tmp_CachedObj); Obstacles.Add(thisObstacle); } } continue; #endregion } if (tmp_CachedObj.ObjectShouldBeRecreated) { //This is where we create the real object after its done with SNO Update. //Specific updates if (tmp_CachedObj.Actortype.Value == ActorType.Item) { tmp_CachedObj = new CacheItem(tmp_CachedObj); } else if (tmp_CachedObj.Actortype.Value == ActorType.Monster) { if (!tmp_CachedObj.IsSummonedPet) { tmp_CachedObj = new CacheUnit(tmp_CachedObj); } else { PetTypes PetType = (PetTypes)TheCache.ObjectIDCache.UnitPetEntries[tmp_CachedObj.SNOID].ObjectType; #region Summoner ID Check // Get the summoned-by info, cached if possible if (!tmp_CachedObj.SummonerID.HasValue) { try { tmp_CachedObj.SummonerID = thisObj.CommonData.GetAttribute <int>(ActorAttributeType.SummonedByACDID); } catch (Exception ex) { //Logger.DBLog.InfoFormat("[Funky] Safely handled exception getting summoned-by info [" + tmp_CachedObj.SNOID.ToString(CultureInfo.InvariantCulture) + "]"); //Logger.DBLog.DebugFormat(ex.ToString()); continue; } } if (FunkyGame.Hero.iMyDynamicID != tmp_CachedObj.SummonerID.Value) { BlacklistCache.IgnoreThisObject(tmp_CachedObj, false, false); tmp_CachedObj.NeedsRemoved = true; continue; } #endregion tmp_CachedObj = new CachePet(tmp_CachedObj, PetType); } } else if (tmp_CachedObj.Actortype.Value == ActorType.Gizmo) { if (CheckFlag(tmp_CachedObj.targetType.Value, TargetType.Interactables)) { tmp_CachedObj = new CacheInteractable(tmp_CachedObj); } else { tmp_CachedObj = new CacheDestructable(tmp_CachedObj); } } //Update Properties (currently only for units) try { tmp_CachedObj.UpdateProperties(); } catch { Logger.Write(LogLevel.Cache, "Failed to update properties for {0}", tmp_CachedObj.DebugStringSimple); } } if (!tmp_CachedObj.UpdateData()) { //Logger.Write(LogLevel.Cache, "Update Failed for {0}", tmp_CachedObj.DebugStringSimple); if (!tmp_CachedObj.IsStillValid()) { tmp_CachedObj.NeedsRemoved = true; } continue; } //Obstacle cache if (tmp_CachedObj.Obstacletype.Value != ObstacleType.None && (CheckFlag(tmp_CachedObj.targetType.Value, TargetType.ServerObjects))) { CacheObstacle thisObstacleObj; if (!Obstacles.TryGetValue(tmp_CachedObj.RAGUID, out thisObstacleObj)) { CacheServerObject newobj = new CacheServerObject(tmp_CachedObj); Obstacles.Add(tmp_CachedObj.RAGUID, newobj); //Add nearby objects to our collection (used in navblock/obstaclecheck methods to reduce queries) if (CacheIDLookup.hashSNONavigationObstacles.Contains(newobj.SNOID)) { Navigation.Navigation.MGP.AddCellWeightingObstacle(newobj.SNOID, newobj.Radius); } } else { if (thisObstacleObj.targetType.Value == TargetType.Unit) { //Since units position requires updating, we update using the CacheObject thisObstacleObj.Position = tmp_CachedObj.Position; Obstacles[tmp_CachedObj.RAGUID] = thisObstacleObj; } } } //cache it if (Objects.ContainsKey(tmp_CachedObj.RAGUID)) { Objects[tmp_CachedObj.RAGUID] = tmp_CachedObj; } else { Objects.Add(tmp_CachedObj.RAGUID, tmp_CachedObj); } } //End of Loop } // End of Framelock //Tally up unseen objects. var UnseenObjects = Objects.Keys.Where(O => !hashDoneThisRactor.Contains(O)).ToList(); if (UnseenObjects.Any()) { for (int i = 0; i < UnseenObjects.Count(); i++) { Objects[UnseenObjects[i]].LoopsUnseen++; } } //Trim our collection every 5th refresh. UpdateLoopCounter++; if (UpdateLoopCounter > 4) { UpdateLoopCounter = 0; //Now flag any objects not seen for 5 loops. Gold/Globe only 1 loop. foreach (var item in Objects.Values.Where(CO => (CO.LoopsUnseen >= 5 || //5 loops max.. (CO.targetType.HasValue && (CheckFlag(CO.targetType.Value, TargetType.Gold | TargetType.Globe)) && CO.LoopsUnseen > 0)))) //gold/globe only 1 loop! { item.NeedsRemoved = true; } } CheckForCacheRemoval(); _lastUpdatedCacheCollection = DateTime.Now; return(true); }
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); }