private bool updateIsMelee()
        {
            _meleeTarget = null;

            var weapon = _motor.EquippedWeapon;

            if (!weapon.HasMelee || weapon.Gun != null)
            {
                return(false);
            }

            var minDist = 0f;

            for (int i = 0; i < AIUtil.FindActors(_motor.transform.position, MeleeRadius, _actor); i++)
            {
                var actor = AIUtil.Actors[i];

                if (actor.Side == _actor.Side)
                {
                    continue;
                }

                var dist = Vector3.Distance(_motor.transform.position, actor.transform.position);

                if (_meleeTarget == null || dist < minDist)
                {
                    _meleeTarget = actor;
                    minDist      = dist;
                }
            }

            return(_meleeTarget != null);
        }
Exemple #2
0
        private bool checkIncomingCollisions(Vector3 ownMovement, float speed)
        {
            var count = AIUtil.FindActors(transform.position, ObstructionRadius, _actor);

            var ownMovementMagnitude = ownMovement.magnitude;
            var hasOwnMovement       = ownMovementMagnitude > 0.25f;
            var ownDirection         = ownMovement / ownMovementMagnitude;

            var closestDot       = 0f;
            var closestVector    = Vector3.zero;
            var closestDirection = Vector3.zero;
            var closestPosition  = Vector3.zero;
            var isClosestPrimary = false;
            var isClosestStatic  = false;
            var hasClosest       = false;

            for (int i = 0; i < count; i++)
            {
                var other = AIUtil.Actors[i];

                if (other.Side != _actor.Side && other.IsAggressive && _actor.IsAggressive)
                {
                    continue;
                }

                Vector3 velocity;
                float   magnitude;

                var movement = _movements.ContainsKey(other) ? _movements[other] : null;
                var isStatic = false;

                if (movement != null && movement._isAvoidingMover)
                {
                    velocity  = movement._avoidDirection;
                    magnitude = 1;
                }
                else
                {
                    velocity  = other.Motor.MovementDirection;
                    magnitude = velocity.magnitude;

                    if (magnitude < 0.1f)
                    {
                        var body = other.Body;

                        if (body == null)
                        {
                            continue;
                        }

                        velocity  = body.velocity;
                        magnitude = velocity.magnitude;

                        if (magnitude < 0.1f)
                        {
                            if (hasOwnMovement)
                            {
                                isStatic  = true;
                                velocity  = -ownMovement;
                                magnitude = 1;
                            }
                            else
                            {
                                continue;
                            }
                        }
                    }
                }

                var direction = velocity / magnitude;

                if (hasOwnMovement && Vector3.Dot(ownDirection, direction) > -0.5f)
                {
                    continue;
                }

                var vector = (transform.position - other.transform.position).normalized;
                var dot    = Vector3.Dot(direction, vector);

                if (dot < 0.7f)
                {
                    continue;
                }

                var isPrimary = (movement == null ? true : !movement._isAvoidingMover) && !isStatic;

                if (!hasClosest || (isClosestStatic && !isStatic) || (isPrimary && !isClosestPrimary) || (isPrimary && dot > closestDot) || (!isPrimary && !isClosestPrimary && dot > closestDot))
                {
                    hasClosest       = true;
                    isClosestPrimary = isPrimary;
                    isClosestStatic  = isStatic;
                    closestPosition  = other.transform.position;
                    closestDirection = direction;
                    closestVector    = vector;
                    closestDot       = dot;
                }
            }

            if (hasClosest)
            {
                if (!isClosestPrimary && !isClosestStatic && !hasOwnMovement && canMoveInDirection(closestVector))
                {
                    return(avoid(closestVector, speed));
                }

                var point    = Util.FindClosestToPath(closestPosition, closestPosition + closestDirection * 100, transform.position);
                var vector   = transform.position - point;
                var distance = vector.magnitude;

                if (distance < 0.1f)
                {
                    var right = Vector3.Cross(closestVector, Vector3.up);
                    var left  = -right;

                    if (hasOwnMovement && isClosestStatic)
                    {
                        right = (right + ownMovement).normalized;
                        left  = (left + ownMovement).normalized;
                    }

                    if (canMoveInDirection(right))
                    {
                        return(avoid(right, speed));
                    }

                    if (canMoveInDirection(left))
                    {
                        return(avoid(left, speed));
                    }
                }
                else
                {
                    var direction = vector / distance;

                    if (hasOwnMovement && isClosestStatic)
                    {
                        direction = (direction + ownMovement).normalized;
                    }

                    if (canMoveInDirection(direction))
                    {
                        return(avoid(direction, speed));
                    }
                }

                if (isClosestPrimary && !isClosestStatic && !hasOwnMovement && canMoveInDirection(closestVector))
                {
                    return(avoid(closestVector, speed));
                }
            }

            return(false);
        }
Exemple #3
0
        private bool isValidCover(Cover cover, Vector3 position, int direction, bool checkPath, bool avoidPivot = true)
        {
            if (cover == _unreachableCover)
            {
                return(false);
            }

            if (_isKeepingCloseTo && Vector3.Distance(position, _keepCloseTo.Position) > _keepCloseTo.Distance)
            {
                return(false);
            }

            if (!_hasPivot)
            {
                if (!AIUtil.IsCoverPositionFree(cover, position, 1, _actor))
                {
                    return(false);
                }

                return(true);
            }

            if (!_hasCachedEnemies)
            {
                _cachedEnemyCount = 0;
                _hasCachedEnemies = true;

                var totalActorCount = AIUtil.FindActors(position, MinDefenselessDistance, _actor);

                if (totalActorCount > 0)
                {
                    var enemyCount = 0;
                    for (int i = 0; i < totalActorCount; i++)
                    {
                        if (AIUtil.Actors[i].Side != _actor.Side)
                        {
                            enemyCount++;
                        }
                    }

                    if (enemyCount > 0)
                    {
                        if (_cachedEnemies == null || _cachedEnemies.Length < enemyCount)
                        {
                            _cachedEnemies = new Actor[enemyCount];
                        }

                        var index = 0;

                        for (int i = 0; i < totalActorCount; i++)
                        {
                            if (AIUtil.Actors[i].Side != _actor.Side)
                            {
                                _cachedEnemies[index++] = AIUtil.Actors[i];
                            }
                        }

                        _cachedEnemyCount = index;
                    }
                }
            }

            for (int i = 0; i < _cachedEnemyCount; i++)
            {
                var enemy = _cachedEnemies[i];

                if (enemy.Side != _actor.Side)
                {
                    var enemyPosition = enemy.transform.position;
                    var distance      = Vector3.Distance(position, enemyPosition);

                    if (distance < AvoidDistance)
                    {
                        return(false);
                    }

                    if (!AIUtil.IsGoodAngle(MaxTallCoverThreatAngle,
                                            MaxLowCoverThreatAngle,
                                            cover,
                                            position,
                                            enemyPosition,
                                            cover.IsTall))
                    {
                        return(false);
                    }
                }
            }

            if (_isPivotThreat)
            {
                var distance = Vector3.Distance(position, _pivotPosition);

                if (_hasMaxPivotDistance && distance > _maxPivotDistance)
                {
                    return(false);
                }

                var aimPosition = position;

                if (AIUtil.IsObstructed(aimPosition + (_actor.StandingTopPosition - transform.position),
                                        _pivotPosition + Vector3.up * 2))
                {
                    return(false);
                }
            }
            else
            {
                var distance = Vector3.Distance(position, _pivotPosition);

                if (_hasMaxPivotDistance && distance > _maxPivotDistance)
                {
                    return(false);
                }

                if (!AIUtil.IsGoodAngle(MaxDefenseAngle,
                                        MaxDefenseAngle,
                                        cover,
                                        _pivotPosition,
                                        position,
                                        cover.IsTall))
                {
                    return(false);
                }
            }

            if (!AIUtil.IsCoverPositionFree(cover, position, 1, _actor))
            {
                return(false);
            }

            if (checkPath)
            {
                if (NavMesh.CalculatePath(transform.position, position, 1, _path))
                {
                    if (avoidPivot)
                    {
                        var count = _path.GetCornersNonAlloc(_corners);

                        for (int i = 0; i < count; i++)
                        {
                            var a = i == 0 ? transform.position : _corners[i - 1];
                            var b = _corners[i];

                            var closest = Util.FindClosestToPath(a, b, _pivotPosition);

                            if (Vector3.Distance(closest, _pivotPosition) < AvoidDistance)
                            {
                                return(false);
                            }
                        }
                    }
                }
                else
                {
                    return(false);
                }
            }

            return(true);
        }