Ejemplo n.º 1
0
        private bool isValidSide(Vector3 vector)
        {
            if (!_motor.IsFree(vector, 0.5f, 0.1f))
            {
                return(false);
            }

            if (AIUtil.IsObstructed(transform.position + Vector3.up * 2, _target + Vector3.up * 2, 1000))
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        private void Update()
        {
            if (!_actor.IsAlive)
            {
                return;
            }

            var wantsToAlwaysAim = AlwaysAim && _motor.Cover == null;

            if (wantsToAlwaysAim)
            {
                Equip(_motor);
            }

            if (_motor.Gun == null)
            {
                return;
            }

            if (_isReloading)
            {
                _isReloading = !_motor.IsGunReady;
            }
            else if (_motor.Gun != null && _motor.Gun.IsClipEmpty)
            {
                _isReloading = true;
                _motor.InputReload();
            }

            var isObstructed = false;

            if (_isFiring && _isAimingAtAPosition)
            {
                var origin = transform.position;

                if (_motor.Cover != null && _motor.Cover.IsTall)
                {
                    if (_motor.CoverDirection > 0 && _motor.IsNearRightCorner)
                    {
                        origin = _motor.Cover.RightCorner(transform.position.y, _motor.CoverSettings.CornerOffset.x);
                    }
                    else if (_motor.CoverDirection < 0 && _motor.IsNearLeftCorner)
                    {
                        origin = _motor.Cover.LeftCorner(transform.position.y, _motor.CoverSettings.CornerOffset.x);
                    }
                }

                var start    = origin + Vector3.up * 2;
                var distance = Vector3.Distance(start, _aim);

                if (distance > 1.5f)
                {
                    isObstructed = AIUtil.IsObstructed(start, _aim, distance - 1.5f);
                }
            }

            if (_motor.Cover == null && (_isAiming || wantsToAlwaysAim) && !_isReloading)
            {
                _motor.InputAim();
            }

            if (_isFiring && !_isReloading && !isObstructed)
            {
                var cycleDuration = _motor.Cover != null ? CoverBursts.CycleDuration : Bursts.CycleDuration;

                if (_fireCycle >= cycleDuration)
                {
                    if (_isFiringABurst)
                    {
                        _gunBurstsWereCalculatedFor = _motor.Gun;
                        _burstBulletCount           = _bulletCountAtStart - _motor.Gun.Clip;
                    }

                    _isFiringABurst = false;
                    _fireCycle     -= cycleDuration;

                    if (_gunBurstsWereCalculatedFor == _motor.Gun && _motor.Gun.Clip < _burstBulletCount)
                    {
                        _isReloading = true;
                        _motor.InputReload();
                    }
                }

                if (_motor.Cover != null)
                {
                    if (_fireCycle >= CoverBursts.Wait)
                    {
                        _motor.InputAim();

                        if (_fireCycle >= CoverBursts.Wait + CoverBursts.IntroDuration &&
                            _fireCycle < CoverBursts.CycleDuration - CoverBursts.OutroDuration)
                        {
                            if (!_isFiringABurst)
                            {
                                _bulletCountAtStart = _motor.Gun.Clip;
                                _isFiringABurst     = true;
                            }

                            if (_motor.IsGunReady)
                            {
                                _motor.InputFireOnCondition(_actor.Side);
                            }
                        }
                    }
                }
                else
                {
                    _motor.InputAim();

                    if (_fireCycle >= Bursts.Wait)
                    {
                        if (!_isFiringABurst)
                        {
                            _bulletCountAtStart = _motor.Gun.Clip;
                            _isFiringABurst     = true;
                        }

                        if (_motor.IsGunReady)
                        {
                            _motor.InputFireOnCondition(_actor.Side);
                        }
                    }
                }

                _fireCycle += Time.deltaTime;
            }
            else
            {
                _fireCycle      = 0;
                _isFiringABurst = false;
            }
        }
Ejemplo n.º 4
0
        private bool isValidCover(Cover cover, Vector3 position, int direction, bool checkPath)
        {
            if (!_hasThreat)
            {
                return(true);
            }

            if (Vector3.Distance(position, _threatPosition) < AvoidDistance)
            {
                return(false);
            }

            if (!AIUtil.IsGoodAngle(MaxTallCoverAngle,
                                    MaxLowCoverAngle,
                                    cover,
                                    position,
                                    _threatPosition,
                                    cover.IsTall))
            {
                return(false);
            }

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

            var aimPosition = position;

            if (cover.IsTall)
            {
                var angle = Util.AngleOfVector(_threatPosition - position);

                if (direction > 0)
                {
                    if (!cover.IsFrontField(angle, _motor.CoverSettings.Angles.TallRightCornerFront))
                    {
                        return(false);
                    }

                    if (!cover.IsRight(angle, _motor.CoverSettings.Angles.RightCorner, false))
                    {
                        return(false);
                    }

                    aimPosition = cover.RightCorner(cover.Bottom, _motor.CoverSettings.CornerOffset.x);
                }
                else if (direction < 0)
                {
                    if (!cover.IsFrontField(angle, _motor.CoverSettings.Angles.TallLeftCornerFront))
                    {
                        return(false);
                    }

                    if (!cover.IsLeft(angle, _motor.CoverSettings.Angles.LeftCorner, false))
                    {
                        return(false);
                    }

                    aimPosition = cover.LeftCorner(cover.Bottom, _motor.CoverSettings.CornerOffset.x);
                }
            }

            if (AIUtil.IsObstructed(aimPosition + (_actor.StandingTopPosition - transform.position),
                                    _threatPosition + Vector3.up * 2,
                                    100))
            {
                return(false);
            }

            if (checkPath)
            {
                if (Vector3.Distance(transform.position, _threatPosition) > AvoidDistance)
                {
                    if (NavMesh.CalculatePath(transform.position, position, 1, _path))
                    {
                        for (int i = 0; i < _path.GetCornersNonAlloc(_corners); i++)
                        {
                            var a = i == 0 ? transform.position : _corners[i - 1];
                            var b = _corners[i];

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

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

            return(true);
        }