예제 #1
0
        /// <summary>
        /// Updates the target situation to take cover. Returns true if a cover was found.
        /// </summary>
        public static bool TakeCover(AIController controller, ref AISituation situation)
        {
            var currentVectorToTarget   = situation.ThreatGroundPosition - situation.CurrentPosition;
            var currentDistanceToTarget = currentVectorToTarget.magnitude;

            Cover   result             = null;
            float   resultPathDistance = 0;
            int     resultDirection    = 0;
            Vector3 resultPosition     = situation.CurrentPosition;

            var path    = new NavMeshPath();
            var corners = new Vector3[32];

            var isAlreadyTooClose = currentDistanceToTarget <= controller.Distances.MinEnemy || currentDistanceToTarget <= controller.Cover.MinCoverToEnemyDistance;

            var covers = new List <CoverItem>();

            foreach (var collider in Physics.OverlapSphere(controller.transform.position, controller.Cover.MaxDistance, 0x1 << 8, QueryTriggerInteraction.Collide))
            {
                if (!collider.isTrigger)
                {
                    continue;
                }

                var cover = CoverSearch.GetCover(collider.gameObject);

                if (cover == null || cover == situation.CurrentCover)
                {
                    continue;
                }

                var item = new CoverItem();
                item.Cover  = cover;
                item.IsTall = cover.IsTall(controller.Motor.CoverSettings.TallThreshold);

                if (item.IsTall)
                {
                    item.Direction = cover.ClosestCornerTo(situation.CurrentPosition, controller.Motor.CoverSettings.CornerAimTriggerDistance, out item.Point);
                }
                else
                {
                    item.Point = cover.ClosestPointTo(situation.CurrentPosition, controller.Motor.CoverSettings.LowSideEnterRadius, 0.3f);
                }

                if (float.IsNaN(item.Point.x) || float.IsNaN(item.Point.z))
                {
                    continue;
                }

                item.Point.y  = cover.Bottom;
                item.Distance = Vector3.Distance(controller.transform.position, item.Point);

                covers.Add(item);
            }

            foreach (var item in covers.OrderBy(o => o.Distance))
            {
                var isTall         = item.IsTall;
                var cover          = item.Cover;
                var point          = item.Point;
                var coverDirection = item.Direction;

                if (!AIUtil.IsGoodAngle(controller, cover, point, situation.ThreatGroundPosition, isTall))
                {
                    continue;
                }

                var distanceToTarget = Vector3.Distance(situation.ThreatGroundPosition, point);

                if (distanceToTarget < controller.Distances.MinEnemy ||
                    distanceToTarget < controller.Cover.MinCoverToEnemyDistance)
                {
                    continue;
                }

                if (situation.CurrentCover != null && Vector3.Distance(situation.CurrentPosition, point) < controller.Cover.MinSwitchDistance)
                {
                    continue;
                }

                if ((controller.Health == null || controller.Health.Health > controller.Fighting.MinHealth))
                {
                    if (isTall)
                    {
                        Vector3 aimPoint;
                        coverDirection = cover.ClosestCornerTo(point, -controller.Motor.CoverSettings.CornerOffset.x, out aimPoint);

                        if (!AIUtil.IsInSight(controller, aimPoint, situation.ThreatStandingTopPosition))
                        {
                            continue;
                        }
                    }
                    else if (!AIUtil.IsInSight(controller, point, situation.ThreatStandingTopPosition))
                    {
                        continue;
                    }
                }

                var distanceToOrigin = Vector3.Distance(situation.CurrentPosition, point);

                if (situation.CurrentCover == null)
                {
                    if (distanceToOrigin > controller.Cover.MaxDistance)
                    {
                        continue;
                    }
                }
                else
                if (distanceToOrigin > controller.Cover.MaxSwitchDistance)
                {
                    continue;
                }

                var areThereFriends = false;

                {
                    var hasChangedPosition = false;

                    Vector3 side;

                    if (Vector3.Dot((point - situation.CurrentPosition).normalized, cover.Right) > 0)
                    {
                        side = cover.Right;
                    }
                    else
                    {
                        side = cover.Left;
                    }

                    do
                    {
                        hasChangedPosition = false;

                        if (AIUtil.IsCoverPositionTooCloseToFriends(cover, controller, point))
                        {
                            var next = point + side * 0.5f;

                            if (cover.IsInFront(next, false))
                            {
                                point = next;
                                hasChangedPosition = true;
                            }
                            else
                            {
                                areThereFriends = true;
                            }
                        }
                    }while (hasChangedPosition);
                }

                if (areThereFriends)
                {
                    continue;
                }

                var isOk = false;

                NavMesh.CalculatePath(situation.CurrentPosition, point, NavMesh.AllAreas, path);

                float pathDistance = 0f;

                var count = path.GetCornersNonAlloc(corners);

                if (count < 2)
                {
                    continue;
                }

                var isTooCloseToEnemy = false;

                for (int i = 1; i < count; i++)
                {
                    pathDistance += Vector3.Distance(corners[i - 1], corners[i]);

                    if (!isAlreadyTooClose)
                    {
                        if (Util.DistanceToSegment(situation.ThreatGroundPosition, corners[i - 1], corners[i]) <= controller.Distances.MinPassing)
                        {
                            isTooCloseToEnemy = true;
                            break;
                        }
                    }
                }

                if (isTooCloseToEnemy)
                {
                    continue;
                }

                if (situation.CurrentCover == null)
                {
                    isOk = result == null || pathDistance < resultPathDistance;
                }
                else if (controller.Health == null || controller.Health.Health > controller.Fighting.MinHealth)
                {
                    isOk = (isAlreadyTooClose || distanceToTarget < currentDistanceToTarget) &&
                           (result == null || pathDistance < resultPathDistance);
                }
                else
                {
                    isOk = distanceToTarget > currentDistanceToTarget && (result == null || pathDistance < resultPathDistance);
                }

                if (isOk)
                {
                    result             = cover;
                    resultPosition     = point;
                    resultPathDistance = pathDistance;
                    resultDirection    = coverDirection;
                    break;
                }
            }

            situation.TargetDirection = resultDirection;

            if (result == null)
            {
                if (situation.IsThreatInCover)
                {
                    ApproachACovered(controller, ref situation);
                }
                else
                {
                    ApproachAFree(controller, ref situation, controller.Agent, controller.Distances.MaxWalkingFight, true);
                }

                return(false);
            }
            else
            {
                situation.IsNewCover     = true;
                situation.TargetCover    = result;
                situation.TargetPosition = resultPosition;

                return(true);
            }
        }
        /// <summary>
        /// Returns an updated situation struct.
        /// </summary>
        public void Update(AIController controller, AISituation previous, bool updateInDetail)
        {
            if (!IsAlerted)
            {
                HasInvestigatedTheLatestAlert = false;
            }
            else if (Threat == null & Vector3.Distance(CurrentPosition, ThreatGroundPosition) < controller.Distances.ThreatInvestigation)
            {
                MarkInvestigated();
            }

            if (HasAnInvestigatedAlert)
            {
                InvestigatedAlertAge += Time.deltaTime;
            }

            // Check grenades
            {
                IsNearGrenade = false;
                float minDist = 1000;

                foreach (var grenade in GrenadeList.All)
                {
                    var vec  = grenade.transform.position - controller.transform.position;
                    var dist = vec.magnitude;

                    if (dist < grenade.ExplosionRadius)
                    {
                        if (!IsNearGrenade || dist < minDist)
                        {
                            minDist                = dist;
                            IsNearGrenade          = true;
                            NearestGrenadePosition = grenade.transform.position;

                            if (Threat == null)
                            {
                                HasInvestigatedTheLatestAlert = false;
                                HasAnInvestigatedAlert        = false;
                                ThreatGroundPosition          = grenade.transform.position;
                            }
                        }
                    }
                }
            }

            // Check friends and enemies.
            if (Threat == null || (!IsAlerted && !IsGettingAlerted))
            {
                var minEnemyInfoTimer = controller.View.EnemySustainTime;

                foreach (var actor in Actors.All)
                {
                    if (actor != controller.Actor)
                    {
                        if (actor.Side != controller.Actor.Side)
                        {
                            if (AIUtil.IsInSight(controller, actor.TopPosition))
                            {
                                IsAlerted = true;
                                ReadEnemyState(actor);
                                break;
                            }
                        }
                        else if (actor.AI != null && actor.AI.IsAlerted)
                        {
                            var vector = actor.transform.position - controller.transform.position;

                            if (vector.magnitude < controller.View.CommunicationDistance)
                            {
                                IsAlerted = true;

                                if (actor.AI.Situation.NoThreatTimer < actor.AI.View.EnemySustainTime &&
                                    minEnemyInfoTimer > actor.AI.Situation.NoThreatTimer)
                                {
                                    TakeEnemyState(actor.AI);
                                }
                            }
                        }
                    }
                }
            }

            // Check friends if they had investigated the same position
            if (IsAlerted && Threat == null && !HasInvestigatedTheLatestAlert)
            {
                foreach (var friend in Actors.All)
                {
                    if (friend != controller.Actor &&
                        friend.Side == controller.Actor.Side &&
                        friend.AI.IsAlerted &&
                        friend.AI.Situation.HasAnInvestigatedAlert &&
                        friend.AI.Situation.InvestigatedAlertAge < 10 &&
                        Vector3.Distance(friend.transform.position, controller.transform.position) < controller.View.CommunicationDistance &&
                        Vector3.Distance(friend.AI.Situation.InvestigatedThreatPosition, ThreatGroundPosition) < controller.Distances.ThreatInvestigation)
                    {
                        MarkInvestigated();
                        break;
                    }
                }
            }


            // Check threats
            if (Threat == null)
            {
                var minDist = 100000f;

                foreach (var alert in Alerts.All)
                {
                    var dist = Vector3.Distance(controller.transform.position, alert.Position);

                    if (dist < alert.Range)
                    {
                        if (dist < minDist)
                        {
                            minDist                       = dist;
                            IsAlerted                     = true;
                            ThreatGroundPosition          = alert.Position;
                            HasAnInvestigatedAlert        = false;
                            HasInvestigatedTheLatestAlert = false;
                        }
                    }
                }
            }

            // React to grenades
            if (IsNoticingGrenade)
            {
                if (GrenadeReaction < float.Epsilon)
                {
                    IsNoticingGrenade = false;
                }
                else
                {
                    GrenadeReaction -= Time.deltaTime;
                    IsNearGrenade    = false;
                }
            }
            else if (IsNearGrenade && !previous.IsNearGrenade)
            {
                GrenadeReaction   = controller.Fighting.GrenadeReactionTime;
                IsNoticingGrenade = true;
                IsNearGrenade     = false;
            }

            if (IsNearGrenade)
            {
                IsAlerted = true;
            }

            // React to being alerted.
            if (IsGettingAlerted)
            {
                if (AlertReaction < float.Epsilon)
                {
                    IsGettingAlerted = false;
                    IsAlerted        = true;
                }
                else
                {
                    AlertReaction -= Time.deltaTime;
                    IsAlerted      = false;
                }
            }
            else if (IsAlerted && !previous.IsAlerted)
            {
                AlertReaction    = controller.Fighting.ReactionTime;
                IsGettingAlerted = true;
                IsAlerted        = false;
            }

            if (previous.TargetCover != null &&
                (controller.Motor.LeftCover == previous.TargetCover || controller.Motor.RightCover == previous.TargetCover || controller.Motor.Cover == previous.TargetCover))
            {
                CurrentCover = previous.TargetCover;
            }
            else
            {
                CurrentCover = controller.Motor.Cover;
            }

            CurrentPosition = controller.transform.position;
            IsGunReady      = controller.Motor.IsGunReady && controller.Motor.Gun.Clip >= controller.Motor.Gun.ClipSize * controller.Fighting.ReloadFraction;

            if (controller.Health != null && Threat != null && Threat.IsAttacking)
            {
                IsRetreating = IsAlerted && controller.Health.Health <= controller.Fighting.MinHealth;
            }
            else
            {
                IsRetreating = false;
            }

            if (IsAlerted)
            {
                var couldSeeTheEnemy = CanSeeTheThreat;
                CanSeeTheThreat = false;

                if (Threat != null)
                {
                    if (couldSeeTheEnemy || updateInDetail)
                    {
                        CanSeeTheThreat = AIUtil.IsInSight(controller, Threat.TopPosition);
                    }

                    if (CanSeeTheThreat)
                    {
                        ReadEnemyState(Threat);
                    }
                    else
                    {
                        NoThreatTimer += Time.deltaTime;

                        if (updateInDetail)
                        {
                            // Check friends and enemies.
                            foreach (var friend in Actors.All)
                            {
                                if (friend != controller.Actor &&
                                    friend.Side == controller.Actor.Side &&
                                    friend.AI != null &&
                                    friend.AI.IsAlerted &&
                                    friend.AI.Situation.CanSeeTheThreat &&
                                    friend.AI.Situation.Threat == Threat)
                                {
                                    var vector = friend.transform.position - controller.transform.position;

                                    if (vector.magnitude < controller.View.CommunicationDistance)
                                    {
                                        TakeEnemyState(friend.AI);
                                    }
                                }
                            }
                        }
                    }
                }

                if (TargetCover != null && updateInDetail)
                {
                    var distanceToThreat = Vector3.Distance(TargetPosition, ThreatGroundPosition);

                    IsTargetCoverGood = distanceToThreat >= controller.Distances.MinEnemy &&
                                        distanceToThreat >= controller.Cover.MinCoverToEnemyDistance &&
                                        AIUtil.IsGoodAngle(controller,
                                                           TargetCover,
                                                           TargetPosition,
                                                           ThreatGroundPosition,
                                                           TargetCover.IsTall(controller.Motor.CoverSettings.TallThreshold)) &&
                                        !AIUtil.IsCoverPositionTooCloseToFriends(TargetCover, controller, TargetPosition);
                }

                if (updateInDetail)
                {
                    if (TargetCover != null && TargetCover.IsTall(controller.Motor.CoverSettings.TallThreshold))
                    {
                        Vector3 aimPoint;

                        if (TargetDirection < 0)
                        {
                            aimPoint = TargetCover.LeftCorner(0, controller.Motor.CoverSettings.CornerOffset.x);
                        }
                        else
                        {
                            aimPoint = TargetCover.RightCorner(0, controller.Motor.CoverSettings.CornerOffset.x);
                        }

                        CanSeeFromTargetPosition = AIUtil.IsInSight(controller, aimPoint, ThreatStandingTopPosition);
                    }
                    else
                    {
                        CanSeeFromTargetPosition = AIUtil.IsInSight(controller, TargetPosition, ThreatStandingTopPosition);
                    }
                }
            }
            else
            {
                if (TargetCover != null && updateInDetail)
                {
                    IsTargetCoverGood = !AIUtil.IsCoverPositionTooCloseToFriends(TargetCover, controller, TargetPosition);
                }

                CanSeeFromTargetPosition = true;
            }
        }
예제 #3
0
        /// <summary>
        /// Returns an updated situation struct.
        /// </summary>
        public void Update(AIController controller, AISituation previous, bool updateInDetail)
        {
            if (!IsAlerted)
            {
                HasInvestigatedTheLatestAlert = false;
            }
            else if (!HasInvestigatedTheLatestAlert && Vector3.Distance(CurrentPosition, InvestigationPosition) < controller.Distances.ThreatInvestigation)
            {
                MarkInvestigated();
            }

            if (HasAnInvestigatedAlert)
            {
                InvestigatedAlertAge += Time.deltaTime;
            }

            if (IsIrritated)
            {
                if (IrritationTime > controller.Fighting.Irritation)
                {
                    IrritationTime = 0;
                    IsIrritated    = false;
                }
                else
                {
                    IrritationTime += Time.deltaTime;
                }
            }
            else
            {
                IrritationTime = 0;
            }

            // Check grenades
            {
                IsNearGrenade = false;
                float minDist = 1000;

                foreach (var grenade in GrenadeList.All)
                {
                    var vec  = grenade.transform.position - controller.transform.position;
                    var dist = vec.magnitude;

                    if (dist < grenade.ExplosionRadius)
                    {
                        if (!IsNearGrenade || dist < minDist)
                        {
                            minDist                = dist;
                            IsNearGrenade          = true;
                            NearestGrenadePosition = grenade.transform.position;

                            if (Threat == null)
                            {
                                HasInvestigatedTheLatestAlert = false;
                                HasAnInvestigatedAlert        = false;
                                IsThreatPositionANewAlert     = true;
                                SetThreatPosition(grenade.transform.position, true);
                            }
                        }
                    }
                }
            }

            // Check friends and enemies.
            if (Threat == null || (!IsAlerted && !IsGettingAlerted))
            {
                foreach (var actor in Actors.All)
                {
                    if (actor != controller.Actor)
                    {
                        if (actor.Side != controller.Actor.Side)
                        {
                            if (AIUtil.IsInSight(controller, actor.TopPosition))
                            {
                                IsAlerted = true;
                                ReadEnemyState(actor);
                                break;
                            }
                        }
                        else if (actor.AI != null && actor.AI.IsAlerted)
                        {
                            var vector = actor.transform.position - controller.transform.position;

                            if (vector.magnitude < controller.View.CommunicationDistance)
                            {
                                IsAlerted = true;

                                if (actor.AI.State != AIState.investigate)
                                {
                                    if (actor.AI.Situation.Threat != null && actor.AI.Situation.HasBetterThreatInfo(actor.AI, ref this))
                                    {
                                        TakeEnemyState(actor.AI);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // Check friends if they had investigated the same position
            if (IsAlerted && !HasInvestigatedTheLatestAlert)
            {
                foreach (var friend in Actors.All)
                {
                    if (friend != controller.Actor &&
                        friend.Side == controller.Actor.Side &&
                        friend.AI != null &&
                        friend.AI.IsAlerted &&
                        friend.AI.Situation.HasAnInvestigatedAlert &&
                        friend.AI.Situation.InvestigatedAlertAge < 4 &&
                        Vector3.Distance(friend.transform.position, controller.transform.position) < controller.View.CommunicationDistance &&
                        Vector3.Distance(friend.AI.Situation.InvestigatedThreatPosition, InvestigationPosition) < controller.Distances.ThreatInvestigation)
                    {
                        MarkInvestigated();
                        break;
                    }
                }
            }

            var isCheckingAThreatInCover = Threat != null && IsThreatInCover && !CanSeeTheThreat;

            // Check threats
            if (Threat == null || CanSeeThatNoThreatAtLastPosition || isCheckingAThreatInCover)
            {
                var minDist = 100000f;

                foreach (var alert in Alerts.All)
                {
                    bool  isOk;
                    Actor newThreat = null;

                    if (Threat != null)
                    {
                        if (alert.Actor == null)
                        {
                            isOk = NoThreatVisibilityTime > 6;
                        }
                        else if (alert.Actor.Side != controller.Actor.Side)
                        {
                            isOk      = true;
                            newThreat = alert.Actor;
                        }
                        else if (alert.Actor.AI != null)
                        {
                            isOk = NoThreatVisibilityTime > 2 && alert.Actor.AI.Situation.NoThreatVisibilityTime < 1;
                        }
                        else
                        {
                            isOk = NoThreatVisibilityTime > 6;
                        }
                    }
                    else
                    {
                        isOk = true;
                    }

                    if (isOk)
                    {
                        var dist = Vector3.Distance(controller.transform.position, alert.Position);

                        if (dist < alert.Range)
                        {
                            if (dist < minDist)
                            {
                                minDist   = dist;
                                IsAlerted = true;

                                HasAnInvestigatedAlert        = false;
                                HasInvestigatedTheLatestAlert = false;

                                if (newThreat != null)
                                {
                                    ReadEnemyState(newThreat);
                                }
                                else
                                {
                                    IsThreatPositionANewAlert = true;
                                    SetThreatPosition(alert.Position, true);
                                }
                            }
                        }
                    }
                }
            }

            // React to grenades
            if (IsNoticingGrenade)
            {
                if (GrenadeReaction < float.Epsilon)
                {
                    IsNoticingGrenade = false;
                }
                else
                {
                    GrenadeReaction -= Time.deltaTime;
                    IsNearGrenade    = false;
                }
            }
            else if (IsNearGrenade && !previous.IsNearGrenade)
            {
                GrenadeReaction   = controller.Fighting.GrenadeReactionTime;
                IsNoticingGrenade = true;
                IsNearGrenade     = false;
            }

            if (IsNearGrenade)
            {
                IsAlerted = true;
            }

            // React to being alerted.
            if (IsGettingAlerted)
            {
                if (AlertReaction < float.Epsilon)
                {
                    IsGettingAlerted = false;
                    IsAlerted        = true;
                }
                else
                {
                    AlertReaction -= Time.deltaTime;
                    IsAlerted      = false;
                }
            }
            else if (IsAlerted && !previous.IsAlerted)
            {
                AlertReaction    = controller.Fighting.ReactionTime;
                IsGettingAlerted = true;
                IsAlerted        = false;
            }

            if (previous.TargetCover != null &&
                (controller.Motor.LeftCover == previous.TargetCover || controller.Motor.RightCover == previous.TargetCover || controller.Motor.Cover == previous.TargetCover))
            {
                CurrentCover = previous.TargetCover;
            }
            else
            {
                CurrentCover = controller.Motor.Cover;
            }

            CurrentPosition = controller.transform.position;
            IsGunReady      = controller.Motor.IsGunReady && controller.Motor.Gun.Clip >= controller.Motor.Gun.ClipSize * controller.Fighting.ReloadFraction;

            if (Threat == null || Threat.IsAggressive)
            {
                WouldLikeToRetreat = controller.Health.Health <= controller.Fighting.MinHealth;
            }
            else
            {
                WouldLikeToRetreat = false;
            }

            if (IsAlerted)
            {
                var couldSeeTheEnemy = CanSeeTheThreat;
                CanSeeTheThreat = false;

                if (Threat != null)
                {
                    var noPatience = NoThreatVisibilityTime > controller.Fighting.Patience;

                    if (couldSeeTheEnemy || updateInDetail)
                    {
                        CanSeeTheThreat = AIUtil.IsInSight(controller, Threat.TopPosition);
                    }

                    if (CanSeeTheThreat)
                    {
                        ReadEnemyState(Threat);

                        if (!couldSeeTheEnemy && noPatience)
                        {
                            IsIrritated = true;
                        }
                    }
                    else
                    {
                        if (noPatience || (NoThreatVisibilityTime > 2 && (!IsThreatInCover || Vector3.Dot(ThreatCoverForward, ThreatGroundPosition - CurrentPosition) > 0)))
                        {
                            if (!IsThreatInCover ||
                                noPatience ||
                                Vector3.Distance(CurrentPosition, ThreatGroundPosition) < controller.Distances.ThreatInvestigation ||
                                AIUtil.IsInSight(controller, (ThreatGroundPosition + ThreatTopPosition) * 0.5f))
                            {
                                CanSeeThatNoThreatAtLastPosition = true;
                            }
                        }

                        NoThreatVisibilityTime += Time.deltaTime;

                        if (updateInDetail)
                        {
                            // Check friends.
                            foreach (var friend in Actors.All)
                            {
                                if (friend != controller.Actor &&
                                    friend.Side == controller.Actor.Side &&
                                    friend.AI != null &&
                                    friend.AI.IsAlerted &&
                                    friend.AI.State != AIState.investigate &&
                                    friend.AI.Situation.Threat == Threat &&
                                    friend.AI.Situation.HasBetterThreatInfo(friend.AI, ref this))
                                {
                                    var vector = friend.transform.position - controller.transform.position;

                                    if (vector.magnitude < controller.View.CommunicationDistance)
                                    {
                                        TakeEnemyState(friend.AI);
                                    }
                                }
                            }
                        }
                    }
                }

                if (TargetCover != null && updateInDetail)
                {
                    var distanceToThreat = Vector3.Distance(TargetPosition, ThreatGroundPosition);

                    IsTargetCoverGood = distanceToThreat >= controller.Distances.MinEnemy &&
                                        distanceToThreat >= controller.Cover.MinCoverToEnemyDistance &&
                                        AIUtil.IsGoodAngle(controller,
                                                           TargetCover,
                                                           TargetPosition,
                                                           ThreatGroundPosition,
                                                           TargetCover.IsTall) &&
                                        !AIUtil.IsCoverPositionTooCloseToFriends(TargetCover, controller, TargetPosition);
                }

                if (updateInDetail)
                {
                    if (IsThreatInCover)
                    {
                        if (CurrentCover != null && CurrentCover.IsTall)
                        {
                            var aimPoint = Vector3.zero;
                            var isGood   = true;

                            if (TargetDirection < 0)
                            {
                                isGood = CurrentCover.IsLeft(Util.AngleOfVector(ThreatStandingTopPosition - CurrentCover.LeftCorner(0)), controller.Motor.CoverSettings.Angles.LeftCorner, false);

                                if (isGood)
                                {
                                    aimPoint = CurrentCover.LeftCorner(0, controller.Motor.CoverSettings.CornerOffset.x);
                                }
                            }
                            else
                            {
                                isGood = CurrentCover.IsRight(Util.AngleOfVector(ThreatStandingTopPosition - CurrentCover.RightCorner(0)), controller.Motor.CoverSettings.Angles.LeftCorner, false);

                                if (isGood)
                                {
                                    aimPoint = CurrentCover.RightCorner(0, controller.Motor.CoverSettings.CornerOffset.x);
                                }
                            }

                            CanSeeFromCurrentPosition = AIUtil.IsInSight(controller, aimPoint, ThreatStandingTopPosition);
                        }
                        else
                        {
                            CanSeeFromCurrentPosition = AIUtil.IsInSight(controller, CurrentPosition, ThreatStandingTopPosition);
                        }
                    }
                    else
                    {
                        CanSeeFromCurrentPosition = CanSeeTheThreat;
                    }
                }
            }
            else
            {
                if (TargetCover != null && updateInDetail)
                {
                    IsTargetCoverGood = !AIUtil.IsCoverPositionTooCloseToFriends(TargetCover, controller, TargetPosition);
                }
            }
        }