コード例 #1
0
ファイル: UnitCluster.cs プロジェクト: BUFORD/Funky
 public UnitCluster(double p_Dist, CacheUnit unit)
     : base(p_Dist, unit)
 {
     ListUnits = new List<CacheUnit>();
     ListUnits.Add(unit);
     NearestMonsterDistance = unit.CentreDistance;
     Info = new ClusterInfo();
     Info.Update(ref unit);
 }
コード例 #2
0
ファイル: ClusterInfo.cs プロジェクト: BUFORD/Funky
        public void Update(ref CacheUnit unit, bool refreshproperties = false)
        {
            UnitCounter++;

            if (unit.UnitMaxHitPointAverageWeight < 0) WeakCounter++; else if (unit.UnitMaxHitPointAverageWeight > 0) StrongCounter++;

            if (unit.IsEliteRareUnique) ElitesCounter++; else if (unit.IsBoss) BossCounter++;

            if (unit.IsFast) FastCounter++;
            if (unit.IsRanged) RangedCounter++;

            if (Bot.Targeting.Cache.Environment.UsesDOTDPSAbility && unit.HasDOTdps.HasValue && unit.HasDOTdps.Value) DOTDPSCounter++;

            if (refreshproperties) UpdateProperties();
        }
コード例 #3
0
ファイル: TargetingCache.cs プロジェクト: BUFORD/Funky
        ///<summary>
        ///Resets/Updates cache and misc vars
        ///</summary>
        private void InitObjectRefresh()
        {
            //Cache last target only if current target is not avoidance (Movement).
            LastCachedTarget = CurrentTarget != null ? CurrentTarget : ObjectCache.FakeCacheObject;

            if (CurrentTarget != null && CurrentTarget.targetType.HasValue && ObjectCache.CheckTargetTypeFlag(CurrentTarget.targetType.Value, TargetType.AvoidanceMovements))
            {
                if (CurrentTarget.targetType.Value == TargetType.Fleeing)
                {
                    LastFleeAction = DateTime.Now;
                    FleeingLastTarget = true;
                }
                else
                {
                    LastAvoidanceMovement = DateTime.Now;
                    AvoidanceLastTarget = true;
                }
            }
            else
            {
                FleeingLastTarget = false;
                AvoidanceLastTarget = false;
            }

            //Traveling Flag Reset
            TravellingAvoidance = false;

            //Reset target
            CurrentTarget = null;
            CurrentUnitTarget = null;

            //Kill Loot Radius Update
            UpdateKillLootRadiusValues();

            // Refresh buffs (so we can check for wrath being up to ignore ice balls and anything else like that)
            Bot.Character.Class.HotBar.RefreshHotbarBuffs();

            // Bunch of variables used throughout
            Bot.Character.Data.PetData.Reset();
            // Reset the counters for monsters at various ranges
            Environment.Reset();

            //Check if we should trim our SNO cache..
            if (DateTime.Now.Subtract(ObjectCache.cacheSnoCollection.lastTrimming).TotalMilliseconds > Bot.Settings.Plugin.UnusedSNORemovalRate)
                ObjectCache.cacheSnoCollection.TrimOldUnusedEntries();

            //Check Cached Object Removal flag
            if (RemovalCheck)
            {
                //Remove flagged objects
                var RemovalObjs = (from objs in ObjectCache.Objects.Values
                                   where objs.NeedsRemoved
                                   select objs.RAGUID).ToList();

                foreach (var item in RemovalObjs)
                {
                    CacheObject thisObj = ObjectCache.Objects[item];

                    //remove prioritized raguid
                    if (Bot.NavigationCache.PrioritizedRAGUIDs.Contains(item))
                        Bot.NavigationCache.PrioritizedRAGUIDs.Remove(item);

                    //Blacklist flag check
                    if (thisObj.BlacklistFlag != BlacklistType.None)
                        BlacklistCache.AddObjectToBlacklist(thisObj.RAGUID, thisObj.BlacklistFlag);

                    ObjectCache.Objects.Remove(thisObj.RAGUID);
                }

                RemovalCheck = false;
            }

            //Increase counter, clear entries if overdue.
            ObjectCache.Obstacles.AttemptToClearEntries();

            //Non-Combat behavior we reset temp blacklist so we don't get killed by "ignored" units..
            if (Bot.IsInNonCombatBehavior)
                BlacklistCache.CheckRefreshBlacklists(10);

            //Check Gold Inactivity
            Bot.Game.GoldTimeoutChecker.CheckTimeoutTripped();
        }
コード例 #4
0
ファイル: TargetingCache.cs プロジェクト: BUFORD/Funky
        internal void OnTargetChanged(TargetChangedArgs e)
        {
            Logger.Write(LogLevel.Target, "Changed Object: {0}", MakeStringSingleLine(e.newObject.DebugString));

            LastChangeOfTarget = DateTime.Now;
            if (Bot.Settings.EnableWaitAfterContainers && CurrentTarget.targetType == TargetType.Container)
            {
                //Herbfunks delay for container loot.
                lastHadContainerAsTarget = DateTime.Now;

                if (CurrentTarget.IsResplendantChest)
                    lastHadRareChestAsTarget = DateTime.Now;
            }

            // We're sticking to the same target, so update the target's health cache to check for stucks
            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;
            }

            bWholeNewTarget = true;
            bPickNewAbilities = true;

            TargetChangeHandler handler = TargetChanged;
            if (handler != null)
            {
                handler(this, e);
            }
        }
コード例 #5
0
        internal static TargetProperties EvaluateUnitProperties(CacheUnit unit)
        {
            TargetProperties properties=TargetProperties.None;

                if (unit.IsBoss)
                     properties|=TargetProperties.Boss;

                if (unit.IsBurrowableUnit)
                     properties|=TargetProperties.Burrowing;

                if (unit.MonsterMissileDampening)
                     properties|=TargetProperties.MissileDampening;

                if (unit.IsMissileReflecting)
                     properties|=TargetProperties.MissileReflecting;

                if (unit.MonsterShielding)
                     properties|=TargetProperties.Shielding;

                if (unit.IsStealthableUnit)
                     properties|=TargetProperties.Stealthable;

                if (unit.IsSucideBomber)
                     properties|=TargetProperties.SucideBomber;

                if (unit.IsTreasureGoblin)
                     properties|=TargetProperties.TreasureGoblin;

                if (unit.IsFast)
                     properties|=TargetProperties.Fast;

                if (unit.IsEliteRareUnique)
                     properties|=TargetProperties.RareElite;

                if (unit.MonsterUnique)
                     properties|=TargetProperties.Unique;

                if (unit.ObjectIsSpecial)
                     properties|=TargetProperties.IsSpecial;

                if (unit.CurrentHealthPct.HasValue&&unit.CurrentHealthPct.Value==1d)
                     properties|=TargetProperties.FullHealth;

                if (unit.UnitMaxHitPointAverageWeight<0)
                     properties|=TargetProperties.Weak;

                if (unit.IsRanged)
                     properties|=TargetProperties.Ranged;

                if (unit.IsTargetableAndAttackable)
                     properties|=TargetProperties.TargetableAndAttackable;

                if (unit.HasDOTdps.HasValue&&unit.HasDOTdps.Value)
                     properties|=TargetProperties.DOTDPS;

                if (unit.RadiusDistance<10f)
                     properties|=TargetProperties.CloseDistance;

                if (unit.MonsterReflectDamage)
                     properties|=TargetProperties.ReflectsDamage;

                if (unit.MonsterElectrified)
                    properties |= TargetProperties.Electrified;

                if (unit.MonsterNormal)
                    properties |= TargetProperties.Normal;

                return properties;
        }
コード例 #6
0
ファイル: ObjectCache.cs プロジェクト: BUFORD/Funky
        ///<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;
        }
コード例 #7
0
ファイル: PlayerClass.cs プロジェクト: BUFORD/Funky
        internal List<Skill> ReturnAllUsableAbilities(CacheUnit obj, bool IgnoreOutOfRange = false)
        {
            //Reset default attack can use
            CanUseDefaultAttack = !Abilities.ContainsKey(DefaultAttack.Power) ? false : true;

            ConditionCriteraTypes criterias = ConditionCriteraTypes.All;

            //Although the unit is a cluster exception.. we should verify it is not a clustered object.
            if (obj.IsClusterException && obj.BeingIgnoredDueToClusterLogic)
            {
                criterias = ConditionCriteraTypes.SingleTarget;
            }

            List<Skill> UsableAbilities = new List<Skill>();
            foreach (var item in SortedAbilities)
            {
                //Check precast conditions
                if (!item.CheckPreCastConditionMethod()) continue;

                //Check Combat Conditions!
                if (!item.CheckCombatConditionMethod(criterias))
                {
                    continue;
                }

                //Check if we can execute or if it requires movement
                if (IgnoreOutOfRange)
                {
                    if (item.DestinationVector != Bot.Character.Data.Position)
                        continue;
                }

                Skill ability = item;
                Skill.SetupAbilityForUse(ref ability);
                UsableAbilities.Add(ability);
            }

            return UsableAbilities;
        }
コード例 #8
0
ファイル: PlayerClass.cs プロジェクト: BUFORD/Funky
        ///<summary>
        ///Sets criteria based on object given.
        ///</summary>
        internal virtual Skill AbilitySelector(CacheUnit obj, bool IgnoreOutOfRange = false)
        {
            //Reset default attack can use
            CanUseDefaultAttack = !HotBar.HotbarPowers.Contains(DefaultAttack.Power) ? false : true;
            //Reset waiting for special!
            bWaitingForSpecial = false;

            ConditionCriteraTypes criterias = ConditionCriteraTypes.All;

            //Although the unit is a cluster exception.. we should verify it is not a clustered object.
            if (obj.IsClusterException && obj.BeingIgnoredDueToClusterLogic)
            {
                criterias = ConditionCriteraTypes.SingleTarget;
            }

            return AbilitySelector(criterias, IgnoreOutOfRange);
        }
コード例 #9
0
ファイル: UnitCluster.cs プロジェクト: BUFORD/Funky
        private void UpdateProperties(CacheUnit unit)
        {
            float distance = unit.CentreDistance;
            if (distance < this.NearestMonsterDistance)
                this.NearestMonsterDistance = distance;

            Info.Update(ref unit, true);
        }
コード例 #10
0
ファイル: UnitCluster.cs プロジェクト: BUFORD/Funky
        private bool ContainsUnit(CacheUnit unit)
        {
            bool u_Exists = false;

            if (base.RAGUIDS.Contains(unit.RAGUID))
                u_Exists = true;

            return u_Exists;
        }