Example #1
0
        internal void ItemPickupEval(CacheItem item)
        {
            if (OnItemPickupEvaluation == null)
            {//If no event hooked then use default evaluation

                if (Bot.Settings.ItemRules.UseItemRules)
                {
                    Interpreter.InterpreterAction action = ItemRulesEval.checkPickUpItem(item, ItemEvaluationType.PickUp);
                    switch (action)
                    {
                        case Interpreter.InterpreterAction.PICKUP:
                            item.ShouldPickup = true;
                            break;
                        case Interpreter.InterpreterAction.IGNORE:
                            item.ShouldPickup = false;
                            break;
                    }
                }

                if (!item.ShouldPickup.HasValue)
                {
                    //Use Giles Scoring or DB Weighting..
                    item.ShouldPickup =
                           Bot.Settings.ItemRules.ItemRuleGilesScoring ? Backpack.GilesPickupItemValidation(item)
                         : ItemManager.Current.EvaluateItem(item.ref_DiaItem.CommonData, ItemEvaluationType.PickUp); ;
                }
            }
            else
            {
                OnItemPickupEvaluation(item);
            }
        }
Example #2
0
        // **********************************************************************************************
        // *****       Pickup Validation - Determines what should or should not be picked up        *****
        // **********************************************************************************************
        internal static bool GilesPickupItemValidation(CacheItem item)
        {
            // Calculate giles item types and base types etc.
            GilesItemType thisGilesItemType = DetermineItemType(item.InternalName, item.BalanceData.thisItemType, item.BalanceData.thisFollowerType);
            GilesBaseItemType thisGilesBaseType = DetermineBaseType(thisGilesItemType);

            // If it's legendary, we always want it *IF* it's level is right
            if (item.Itemquality >= ItemQuality.Legendary)
            {
                if (Bot.Settings.Loot.MinimumLegendaryItemLevel > 0 && (item.BalanceData.iThisItemLevel >= Bot.Settings.Loot.MinimumLegendaryItemLevel || Bot.Settings.Loot.MinimumLegendaryItemLevel == 1))
                    return true;

                return false;
            }

            // Error logging for DemonBuddy item mis-reading
            ItemType gilesDBItemType = GilesToDBItemType(thisGilesItemType);
            if (gilesDBItemType != item.BalanceData.thisItemType)
            {
                Logger.DBLog.InfoFormat("GSError: Item type mis-match detected: Item Internal=" + item.InternalName + ". DemonBuddy ItemType thinks item type is=" + item.BalanceData.thisItemType + ". Giles thinks item type is=" +
                     gilesDBItemType + ". [pickup]", true);
            }

            switch (thisGilesBaseType)
            {
                case GilesBaseItemType.WeaponTwoHand:
                case GilesBaseItemType.WeaponOneHand:
                case GilesBaseItemType.WeaponRange:
                    // Not enough DPS, so analyse for possibility to blacklist
                    if (item.Itemquality < ItemQuality.Magic1)
                    {
                        // White item, blacklist
                        return false;
                    }
                    if (item.Itemquality >= ItemQuality.Magic1 && item.Itemquality < ItemQuality.Rare4)
                    {
                        if (Bot.Settings.Loot.MinimumWeaponItemLevel[0] == 0 || (Bot.Settings.Loot.MinimumWeaponItemLevel[0] != 0 && item.BalanceData.iThisItemLevel < Bot.Settings.Loot.MinimumWeaponItemLevel[0]))
                        {
                            // Between magic and rare, and either we want no blues, or this level is higher than the blue level we want
                            return false;
                        }
                    }
                    else
                    {
                        if (Bot.Settings.Loot.MinimumWeaponItemLevel[1] == 0 || (Bot.Settings.Loot.MinimumWeaponItemLevel[1] != 0 && item.BalanceData.iThisItemLevel < Bot.Settings.Loot.MinimumWeaponItemLevel[1]))
                        {
                            // Between magic and rare, and either we want no blues, or this level is higher than the blue level we want
                            return false;
                        }
                    }
                    break;
                case GilesBaseItemType.Armor:
                case GilesBaseItemType.Offhand:
                    if (item.Itemquality < ItemQuality.Magic1)
                    {
                        // White item, blacklist
                        return false;
                    }
                    if (item.Itemquality >= ItemQuality.Magic1 && item.Itemquality < ItemQuality.Rare4)
                    {
                        if (Bot.Settings.Loot.MinimumArmorItemLevel[0] == 0 || (Bot.Settings.Loot.MinimumArmorItemLevel[0] != 0 && item.BalanceData.iThisItemLevel < Bot.Settings.Loot.MinimumArmorItemLevel[0]))
                        {
                            // Between magic and rare, and either we want no blues, or this level is higher than the blue level we want
                            return false;
                        }
                    }
                    else
                    {
                        if (Bot.Settings.Loot.MinimumArmorItemLevel[1] == 0 || (Bot.Settings.Loot.MinimumArmorItemLevel[1] != 0 && item.BalanceData.iThisItemLevel < Bot.Settings.Loot.MinimumArmorItemLevel[1]))
                        {
                            // Between magic and rare, and either we want no blues, or this level is higher than the blue level we want
                            return false;
                        }
                    }
                    break;
                case GilesBaseItemType.Jewelry:
                    if (item.Itemquality < ItemQuality.Magic1)
                    {
                        // White item, blacklist
                        return false;
                    }
                    if (item.Itemquality >= ItemQuality.Magic1 && item.Itemquality < ItemQuality.Rare4)
                    {
                        if (Bot.Settings.Loot.MinimumJeweleryItemLevel[0] == 0 || (Bot.Settings.Loot.MinimumJeweleryItemLevel[0] != 0 && item.BalanceData.iThisItemLevel < Bot.Settings.Loot.MinimumJeweleryItemLevel[0]))
                        {
                            // Between magic and rare, and either we want no blues, or this level is higher than the blue level we want
                            return false;
                        }
                    }
                    else
                    {
                        if (Bot.Settings.Loot.MinimumJeweleryItemLevel[1] == 0 || (Bot.Settings.Loot.MinimumJeweleryItemLevel[1] != 0 && item.BalanceData.iThisItemLevel < Bot.Settings.Loot.MinimumJeweleryItemLevel[1]))
                        {
                            // Between magic and rare, and either we want no blues, or this level is higher than the blue level we want
                            return false;
                        }
                    }
                    break;
                case GilesBaseItemType.FollowerItem:
                    if (item.BalanceData.iThisItemLevel < 60 || !Bot.Settings.Loot.PickupFollowerItems || item.Itemquality < ItemQuality.Rare4)
                    {
                        return false;
                    }
                    break;
                case GilesBaseItemType.Gem:
                    if (item.BalanceData.iThisItemLevel < Bot.Settings.Loot.MinimumGemItemLevel ||
                        (thisGilesItemType == GilesItemType.Ruby && !Bot.Settings.Loot.PickupGems[0]) ||
                        (thisGilesItemType == GilesItemType.Emerald && !Bot.Settings.Loot.PickupGems[1]) ||
                        (thisGilesItemType == GilesItemType.Amethyst && !Bot.Settings.Loot.PickupGems[2]) ||
                        (thisGilesItemType == GilesItemType.Topaz && !Bot.Settings.Loot.PickupGems[3]) ||
                        (thisGilesItemType == GilesItemType.Diamond && !Bot.Settings.Loot.PickupGemDiamond))
                    {
                        return false;
                    }
                    break;
                case GilesBaseItemType.Misc:
                    // Note; Infernal keys are misc, so should be picked up here - we aren't filtering them out, so should default to true at the end of this function
                    if (thisGilesItemType == GilesItemType.CraftingMaterial)
                    {
                        if (item.BalanceData.iThisItemLevel == 63 && Bot.Settings.Loot.PickupDemonicEssence)
                            return true;

                        return Bot.Settings.Loot.PickupCraftMaterials;
                    }
                    if (thisGilesItemType == GilesItemType.CraftTome && !Bot.Settings.Loot.PickupCraftTomes)
                    {
                        return false;
                    }
                    if (thisGilesItemType == GilesItemType.CraftingPlan)
                    {
                        if (!Bot.Settings.Loot.PickupCraftPlans) return false;

                        int gamebalanceID = item.BalanceID.Value;

                        if (item.BalanceData.IsBlacksmithPlanSixProperties && !Bot.Settings.Loot.PickupBlacksmithPlanSix) return false;
                        if (item.BalanceData.IsBlacksmithPlanFiveProperties && !Bot.Settings.Loot.PickupBlacksmithPlanFive) return false;
                        if (item.BalanceData.IsBlacksmithPlanFourProperties && !Bot.Settings.Loot.PickupBlacksmithPlanFour) return false;

                        if (item.BalanceData.IsBlacksmithPlanArchonSpaulders && !Bot.Settings.Loot.PickupBlacksmithPlanArchonSpaulders) return false;
                        if (item.BalanceData.IsBlacksmithPlanArchonGauntlets && !Bot.Settings.Loot.PickupBlacksmithPlanArchonGauntlets) return false;
                        if (item.BalanceData.IsBlacksmithPlanRazorspikes && !Bot.Settings.Loot.PickupBlacksmithPlanRazorspikes) return false;

                        if (item.BalanceData.IsJewelcraftDesignAmulet && !Bot.Settings.Loot.PickupJewelerDesignAmulet) return false;
                        if (item.BalanceData.IsJewelcraftDesignFlawlessStarGem && !Bot.Settings.Loot.PickupJewelerDesignFlawlessStar) return false;
                        if (item.BalanceData.IsJewelcraftDesignMarquiseGem && !Bot.Settings.Loot.PickupJewelerDesignMarquise) return false;
                        if (item.BalanceData.IsJewelcraftDesignPerfectStarGem && !Bot.Settings.Loot.PickupJewelerDesignPerfectStar) return false;
                        if (item.BalanceData.IsJewelcraftDesignRadiantStarGem && !Bot.Settings.Loot.PickupJewelerDesignRadiantStar) return false;

                    }
                    if (thisGilesItemType == GilesItemType.InfernalKey)
                    {
                        if (!Bot.Settings.Loot.PickupInfernalKeys) return false;
                    }
                    // Potion filtering
                    if (thisGilesItemType == GilesItemType.HealthPotion)
                    {
                        if (Bot.Settings.Loot.MaximumHealthPotions <= 0)
                            return false;

                        var Potions = Bot.Character.Data.BackPack.ReturnCurrentPotions();

                        if (Potions == null || !Potions.Any() || Bot.Character.Data.BackPack.BestPotionToUse == null)
                            return true;
                        if (Bot.Character.Data.BackPack.BestPotionToUse != null && item.BalanceData.iThisItemLevel < Bot.Character.Data.BackPack.BestPotionToUse.Level)
                            return false;
                        if (Potions.Sum(potions => potions.ThisItemStackQuantity) >= Bot.Settings.Loot.MaximumHealthPotions)
                            return false;
                    }
                    if (thisGilesItemType == GilesItemType.MiscBook && item.BalanceData.iThisItemLevel < Bot.Settings.Loot.MiscItemLevel)
                        return false;

                    break;
                case GilesBaseItemType.HealthGlobe:
                    return false;
                case GilesBaseItemType.Unknown:
                    return false;
                default:
                    return false;
            } // Switch giles base item type
            // Didn't cancel it, so default to true!
            return true;
        }
Example #3
0
        public void DroppedItemLog(CacheItem i)
        {
            CacheBalance thisBalanceData = i.BalanceData;
            GilesItemType thisGilesItemType = Backpack.DetermineItemType(i.InternalName, thisBalanceData.thisItemType, thisBalanceData.thisFollowerType);
            if (thisGilesItemType == GilesItemType.InfernalKey)
            {
                Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.Keys.Dropped++;
                //	 Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.stashedItemTotals[(int)LootIndex.Key]++;
                return;
            }

            switch (thisBalanceData.thisItemType)
            {
                case ItemType.CraftingPage:
                case ItemType.CraftingPlan:
                case ItemType.CraftingReagent:
                    Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.Crafting.Dropped++;
                    //  Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.stashedItemTotals[(int)LootIndex.Crafting]++;
                    break;
                case ItemType.Gem:
                    Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.Gems.Dropped++;
                    // Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.stashedItemTotals[(int)LootIndex.Gem]++;
                    break;
                case ItemType.Amulet:
                case ItemType.Axe:
                case ItemType.Belt:
                case ItemType.Boots:
                case ItemType.Bow:
                case ItemType.Bracer:
                case ItemType.CeremonialDagger:
                case ItemType.Chest:
                case ItemType.Cloak:
                case ItemType.Crossbow:
                case ItemType.Dagger:
                case ItemType.Daibo:
                case ItemType.FistWeapon:
                case ItemType.FollowerSpecial:
                case ItemType.Gloves:
                case ItemType.HandCrossbow:
                case ItemType.Helm:
                case ItemType.Legs:
                case ItemType.Mace:
                case ItemType.MightyBelt:
                case ItemType.MightyWeapon:
                case ItemType.Mojo:
                case ItemType.Orb:
                case ItemType.Polearm:
                case ItemType.Quiver:
                case ItemType.Ring:
                case ItemType.Shield:
                case ItemType.Shoulder:
                case ItemType.Spear:
                case ItemType.SpiritStone:
                case ItemType.Staff:
                case ItemType.Sword:
                case ItemType.VoodooMask:
                case ItemType.Wand:
                case ItemType.WizardHat:
                    if (i.Itemquality.Value == ItemQuality.Legendary)
                    {
                        //Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.stashedItemTotals[3]++;
                        Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.Legendary.Dropped++;
                    }
                    else if (i.Itemquality.Value > ItemQuality.Magic3)
                    {
                        // Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.stashedItemTotals[2]++;
                        Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.Rare.Dropped++;
                    }
                    else
                    {
                        //  Bot.BotStatistics.ProfileStats.CurrentProfile.ItemStats.stashedItemTotals[1]++;
                        Bot.Game.CurrentGameStats.CurrentProfile.LootTracker.Magical.Dropped++;
                    }
                    break;
            }
        }
Example #4
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="level"></param>
        /// <param name="itemQuality"></param>
        /// <param name="itemBaseType"></param>
        /// <param name="itemType"></param>
        /// <param name="isOneHand"></param>
        /// <param name="isTwoHand"></param>
        /// <param name="gameBalanceId"></param>
        private void fillPickupDic(CacheItem item)
        {
            object result;
                itemDic=new Dictionary<string, object>();

                // add log unique key
                itemDic.Add("[KEY]", item.DynamicID.ToString());

                // - BASETYPE ---------------------------------------------------------//
                itemDic.Add("[BASETYPE]", item.BalanceData.thisItemBaseType.ToString());

                // - TYPE -------------------------------------------------------------//
                /// TODO remove this check if it isnt necessary anymore
                if (item.BalanceData.thisItemType==ItemType.Unknown&&(item.InternalName.Contains("Plan")||item.InternalName.Contains("Design")))
                {
                     Logger.DBLog.InfoFormat("There are still buggy itemType infos for craftingPlan around {0} has itemType = {1}", item.InternalName, item.BalanceData.thisItemType);
                     result=ItemType.CraftingPlan.ToString();
                }
                else result=item.BalanceData.thisItemType.ToString();
                itemDic.Add("[TYPE]", result);

                // - QUALITY -------------------------------------------------------//
                itemDic.Add("[QUALITY]", Regex.Replace(item.Itemquality.ToString(), @"[\d-]", string.Empty));
                itemDic.Add("[D3QUALITY]", item.Itemquality.ToString());

                // - ROLL ----------------------------------------------------------//
                float roll;
                if (float.TryParse(Regex.Replace(item.Itemquality.ToString(), @"[^\d]", string.Empty), out roll))
                     itemDic.Add("[ROLL]", roll);
                else
                     itemDic.Add("[ROLL]", 0);

                // - NAME -------------------------------------------------------------//
                itemDic.Add("[NAME]", item.InternalName.ToString().Replace(" ", ""));

                // - LEVEL ------------------------------------------------------------//
                itemDic.Add("[LEVEL]", (float)item.BalanceData.iThisItemLevel);
                itemDic.Add("[ONEHAND]", item.BalanceData.bThisOneHand);
                itemDic.Add("[TWOHAND]", item.BalanceData.bThisTwoHand);
                itemDic.Add("[UNIDENT]", (bool)true);
                itemDic.Add("[INTNAME]", item.InternalName);
                itemDic.Add("[ITEMID]", item.BalanceID.ToString());
        }
Example #5
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        internal InterpreterAction checkPickUpItem(CacheItem item, ItemEvaluationType evaluationType)
        {
            fillPickupDic(item);

                return checkItem(evaluationType);
        }
Example #6
0
        ///<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()
        {
            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))
                    {
                        Vector3 tmp_position;
                        int tmp_acdguid;
                        int tmp_SNOID;

                        #region SNO
                        //Lookup SNO
                        try
                        {
                            tmp_SNOID = thisObj.ActorSNO;
                        }
                        catch (NullReferenceException)
                        {
                            //Logger.DBLog.InfoFormat("Failure to get SNO from object! RaGUID: {0}", tmp_raGUID);
                            continue;
                        }
                        #endregion

                        //check our SNO blacklist
                        if (BlacklistCache.IsSNOIDBlacklisted(tmp_SNOID) && !CacheIDLookup.hashSummonedPets.Contains(tmp_SNOID)) continue;

                        #region Position
                        try
                        {
                            tmp_position = thisObj.Position;
                        }
                        catch (NullReferenceException)
                        {
                            //Logger.DBLog.InfoFormat("Failure to get position vector for RAGUID {0}", tmp_raGUID);
                            continue;
                        }

                        #endregion

                        #region AcdGUID
                        try
                        {
                            tmp_acdguid = thisObj.ACDGuid;
                        }
                        catch (NullReferenceException)
                        {
                            //Logger.DBLog.InfoFormat("Failure to get ACDGUID for RAGUID {0}", tmp_raGUID);
                            continue;
                        }

                        #endregion

                        tmp_CachedObj = new CacheObject(tmp_SNOID, tmp_raGUID, tmp_acdguid, tmp_position);
                    }
                    else
                        //Reset unseen var
                        tmp_CachedObj.LoopsUnseen = 0;

                    //Validate
                    try
                    {
                        if (thisObj.CommonData == null || thisObj.CommonData.ACDGuid != thisObj.ACDGuid) continue;
                    }
                    catch (NullReferenceException)
                    {
                        continue;
                    }

                    //Check if this object is a summoned unit by a player...
                    #region SummonedUnits
                    if (tmp_CachedObj.IsSummonedPet)
                    {
                        // 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;
                            }
                        }

                        //See if this summoned unit was summoned by the bot.
                        if (Bot.Character.Data.iMyDynamicID == tmp_CachedObj.SummonerID.Value)
                        {
                            //Now modify the player data pets count..
                            if (Bot.Character.Class.AC == ActorClass.Monk)
                                Bot.Character.Data.PetData.MysticAlly++;
                            else if (Bot.Character.Class.AC == ActorClass.DemonHunter)
                            {
                                if (CacheIDLookup.hashDHPets.Contains(tmp_CachedObj.SNOID))
                                    Bot.Character.Data.PetData.DemonHunterPet++;
                                else if (CacheIDLookup.hashDHSpikeTraps.Contains(tmp_CachedObj.SNOID) && tmp_CachedObj.CentreDistance <= 50f)
                                    Bot.Character.Data.PetData.DemonHunterSpikeTraps++;
                            }
                            else if (Bot.Character.Class.AC == ActorClass.Witchdoctor)
                            {
                                if (CacheIDLookup.hashZombie.Contains(tmp_CachedObj.SNOID))
                                    Bot.Character.Data.PetData.ZombieDogs++;
                                else if (CacheIDLookup.hashGargantuan.Contains(tmp_CachedObj.SNOID))
                                    Bot.Character.Data.PetData.Gargantuan++;
                            }
                            else if (Bot.Character.Class.AC == ActorClass.Wizard)
                            {
                                //only count when range is within 45f (so we can summon a new one)
                                if (CacheIDLookup.hashWizHydras.Contains(tmp_CachedObj.SNOID) && tmp_CachedObj.CentreDistance <= 45f)
                                    Bot.Character.Data.PetData.WizardHydra++;
                            }
                        }

                        //We return regardless if it was summoned by us or not since this object is not anything we want to deal with..
                        tmp_CachedObj.NeedsRemoved = true;
                        continue;
                    }
                    #endregion

                    //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

                    //Special Cache for Interactable Server Objects
                    if (CheckTargetTypeFlag(tmp_CachedObj.targetType.Value, TargetType.ServerInteractable))
                    {
                        if (!Bot.Game.Profile.InteractableObjectCache.ContainsKey(tmp_CachedObj.RAGUID))
                        {
                            Bot.Game.Profile.InteractableObjectCache.Add(tmp_CachedObj.RAGUID, 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 (CheckTargetTypeFlag(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}", thisObstacle.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)
                    {
                        //Specific updates
                        if (tmp_CachedObj.Actortype.Value == ActorType.Item)
                        {
                            tmp_CachedObj = new CacheItem(tmp_CachedObj);
                        }
                        else if (tmp_CachedObj.Actortype.Value == ActorType.Monster)
                        {
                            tmp_CachedObj = new CacheUnit(tmp_CachedObj);
                        }
                        else if (tmp_CachedObj.Actortype.Value == ActorType.Gizmo)
                        {

                            if (CheckTargetTypeFlag(tmp_CachedObj.targetType.Value, TargetType.Interactables))
                                tmp_CachedObj = new CacheInteractable(tmp_CachedObj);
                            else
                                tmp_CachedObj = new CacheDestructable(tmp_CachedObj);
                        }

                        //Update Properties
                        tmp_CachedObj.UpdateProperties();
                    }

                    if (!tmp_CachedObj.UpdateData())
                    {
                        if (!tmp_CachedObj.IsStillValid())
                            tmp_CachedObj.NeedsRemoved = true;

                        continue;
                    }

                    //Obstacle cache
                    if (tmp_CachedObj.Obstacletype.Value != ObstacleType.None
                          && (CheckTargetTypeFlag(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.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 && (CheckTargetTypeFlag(CO.targetType.Value, TargetType.Gold | TargetType.Globe)) && CO.LoopsUnseen > 0)))) //gold/globe only 1 loop!
                {
                    item.NeedsRemoved = true;
                }
            }

            return true;
        }