Пример #1
0
        /// <summary>
        /// Told by the brains to take a cover closer to the enemy.
        /// </summary>
        public void ToTakeCoverCloseTo(AIBaseRegrouper regrouper)
        {
            _takeAnyCover = false;
            nullCover();

            if (isActiveAndEnabled)
            {
                _takeCloseToRadius = regrouper.Radius;

                var movement = regrouper.GetComponent <AIMovement>();
                _takeCloseToPosition = regrouper.transform.position;

                if (movement != null)
                {
                    _takeCloseToPosition = movement.Destination;
                }

                _covers.Reset(_takeCloseToPosition, MaxCoverDistance);

                _mode     = TakeMode.takeCloseTo;
                _modeWait = 2;
                Message("OnCoverSearch");
            }

            updateRegistration();
        }
Пример #2
0
        /// <summary>
        /// Told by the brains to take a defensive cover near a position.
        /// </summary>
        public void ToTakeDefenseCover(Vector3 position)
        {
            _hasPivot      = true;
            _pivotPosition = position;
            _takeAnyCover  = false;
            _isPivotThreat = false;
            nullCover();

            if (isActiveAndEnabled)
            {
                if (_isKeepingCloseTo)
                {
                    _covers.Reset(_keepCloseTo.Position, _keepCloseTo.Distance);
                }
                else
                {
                    _covers.Reset(transform.position, MaxCoverDistance);
                }

                _mode     = TakeMode.takeDefense;
                _modeWait = 2;
                Message("OnCoverSearch");
            }

            updateRegistration();
        }
Пример #3
0
        /// <summary>
        /// Told by the brains to take a cover closer to the enemy.
        /// </summary>
        public void ToSwitchCover()
        {
            _takeAnyCover = false;
            nullCover();

            if (isActiveAndEnabled)
            {
                if (_isKeepingCloseTo)
                {
                    _covers.Reset(_keepCloseTo.Position, _keepCloseTo.Distance);
                }
                else
                {
                    _covers.Reset(transform.position, MaxCoverDistance);
                }

                _mode     = TakeMode.switchCover;
                _modeWait = 2;
                Message("OnCoverSearch");
            }

            updateRegistration();
        }
Пример #4
0
        private void Update()
        {
            if (_actor == null || !_actor.IsAlive)
            {
                return;
            }

            updateRegistration();

            if (_modeWait > 0)
            {
                _modeWait--;
            }
            else
            {
                switch (_mode)
                {
                case TakeMode.none: break;

                case TakeMode.takeCover:
                {
                    _mode        = TakeMode.none;
                    _targetCover = null;

                    var weapon = _motor.EquippedWeapon;

                    if (weapon.IsNull || !weapon.PreventCovers)
                    {
                        for (int i = 0; i < _covers.Items.Count; i++)
                        {
                            var item = _covers.Items[i];

                            if (isValidCover(item.Cover, item.Position, item.Direction, true, false))
                            {
                                takeCover(item.Cover, item.Position, item.Direction, 1);
                                break;
                            }
                        }
                    }

                    if (_targetCover != null)
                    {
                        Message("OnFoundCover");
                    }
                    else
                    {
                        Message("OnNoCover");
                    }
                }
                break;

                case TakeMode.takeCoverAgainst:
                {
                    _mode        = TakeMode.none;
                    _targetCover = null;

                    var weapon = _motor.EquippedWeapon;

                    if (weapon.IsNull || !weapon.PreventCovers)
                    {
                        var isAlreadyClose = Vector3.Distance(transform.position, _pivotPosition) < AvoidDistance;

                        for (int i = 0; i < _covers.Items.Count; i++)
                        {
                            var item = _covers.Items[i];

                            if (isValidCover(item.Cover, item.Position, item.Direction, true, !isAlreadyClose))
                            {
                                takeCover(item.Cover, item.Position, item.Direction, 1);
                                break;
                            }
                        }
                    }

                    if (_targetCover != null)
                    {
                        Message("OnFoundCover");
                    }
                    else
                    {
                        Message("OnNoCover");
                    }
                }
                break;

                case TakeMode.takeDefense:
                {
                    _mode        = TakeMode.none;
                    _targetCover = null;

                    var weapon = _motor.EquippedWeapon;

                    if (weapon.IsNull || !weapon.PreventCovers)
                    {
                        for (int i = 0; i < _covers.Items.Count; i++)
                        {
                            var item = _covers.Items[i];

                            if (isValidCover(item.Cover, item.Position, item.Direction, true, false))
                            {
                                takeCover(item.Cover, item.Position, item.Direction, 1);
                                break;
                            }
                        }
                    }

                    if (_targetCover != null)
                    {
                        Message("OnFoundCover");
                    }
                    else
                    {
                        Message("OnNoCover");
                    }
                }
                break;

                case TakeMode.switchCover:
                {
                    _mode        = TakeMode.none;
                    _targetCover = null;

                    var weapon = _motor.EquippedWeapon;

                    if (weapon.IsNull || !weapon.PreventCovers)
                    {
                        var currentDistance = Vector3.Distance(transform.position, _pivotPosition);
                        var isAlreadyClose  = currentDistance < AvoidDistance;

                        for (int i = 0; i < _covers.Items.Count; i++)
                        {
                            var item = _covers.Items[i];

                            if (Vector3.Distance(transform.position, item.Position) >= MinSwitchDistance &&
                                Vector3.Distance(item.Position, _pivotPosition) < currentDistance &&
                                isValidCover(item.Cover, item.Position, item.Direction, true, !isAlreadyClose))
                            {
                                takeCover(item.Cover, item.Position, item.Direction, 1);
                                break;
                            }
                        }
                    }

                    if (_targetCover != null)
                    {
                        Message("OnFoundCover");
                    }
                    else
                    {
                        Message("OnNoCover");
                    }
                }
                break;

                case TakeMode.takeCloseTo:
                {
                    _mode        = TakeMode.none;
                    _targetCover = null;

                    var weapon = _motor.EquippedWeapon;

                    if (weapon.IsNull || !weapon.PreventCovers)
                    {
                        for (int i = 0; i < _covers.Items.Count; i++)
                        {
                            var item = _covers.Items[i];

                            if (Vector3.Distance(item.Position, _takeCloseToPosition) <= _takeCloseToRadius)
                            {
                                if (isValidCover(item.Cover, item.Position, item.Direction, true, false))
                                {
                                    takeCover(item.Cover, item.Position, item.Direction, 1);
                                    break;
                                }
                            }
                        }
                    }

                    if (_targetCover != null)
                    {
                        Message("OnFoundCover");
                    }
                    else
                    {
                        Message("OnNoCover");
                    }
                }
                break;
                }
            }

            if (_targetCover == null)
            {
                if (_takeAnyCover && _motor.PotentialCover != null)
                {
                    _targetCover = _motor.PotentialCover;
                    _motor.InputTakeCover();
                }
                else if (!_takeAnyCover && _motor.Cover != null)
                {
                    _motor.InputLeaveCover();
                }
            }

            if (_motor.Cover != _targetCover && _targetCover != null)
            {
                if (_motor.PotentialCover != null &&
                    (_motor.PotentialCover == _targetCover ||
                     _motor.PotentialCover.LeftAdjacent == _targetCover ||
                     _motor.PotentialCover.RightAdjacent == _targetCover))
                {
                    _motor.InputTakeCover();
                }
                else if (_motor.Cover != null && _motor.Cover.LeftAdjacent != _targetCover && _motor.Cover.RightAdjacent != _targetCover)
                {
                    _motor.InputLeaveCover();
                }
                else if (Vector3.Distance(transform.position, _targetPosition) < 0.5f)
                {
                    _motor.InputImmediateCoverSearch();
                }
            }

            if (_targetCover != null)
            {
                var weapon = _motor.EquippedWeapon;

                if (!weapon.IsNull && weapon.PreventCovers)
                {
                    _targetCover = null;
                    Message("OnInvalidCover");
                }
                else if (_hasPivot)
                {
                    if (!isValidCover(_targetCover, _targetPosition, _targetDirection, false))
                    {
                        Message("OnInvalidCover");
                    }
                }
            }

            if (_targetCover != null && _targetCover == _motor.Cover && _targetCover.IsTall)
            {
                if (_targetDirection > 0)
                {
                    _motor.InputStandRight();

                    if (!_motor.IsNearRightCorner)
                    {
                        _motor.InputMovement(new CharacterMovement(_targetCover.Right, 0.5f));
                    }
                }
                else
                {
                    _motor.InputStandLeft();

                    if (!_motor.IsNearLeftCorner)
                    {
                        _motor.InputMovement(new CharacterMovement(_targetCover.Left, 0.5f));
                    }
                }
            }

            if (_targetCover != null && _motor.Cover != null && Vector3.Distance(_actor.transform.position, _targetPosition) < 0.5f &&
                (_motor.Cover == _targetCover ||
                 _motor.Cover.LeftAdjacent == _targetCover ||
                 _motor.Cover.RightAdjacent == _targetCover))
            {
                if (!_hasTakenTheRightCover)
                {
                    _hasTakenTheRightCover = true;
                    Message("OnFinishTakeCover");
                }

                if (!_hasAskedToStopMoving)
                {
                    _hasAskedToStopMoving = true;
                    Message("ToStopMoving");
                }
            }
            else
            {
                _hasAskedToStopMoving = false;
            }

            _hasCachedEnemies = false;
        }