public override bool CanContinue()
        {
            var target = _entity.Target;

            if (target == null)
            {
                return(false);
            }

            if (target.HealthManager.IsDead)
            {
                return(false);
            }


            if (!(target is Player))
            {
                if (_entity.DistanceTo(target) > _targetDistance)
                {
                    return(false);
                }
            }
            else
            {
                if (_entity.DistanceTo(target) > GetTargetDistance((Player)target))
                {
                    return(false);
                }

                if (_entity.CanSee(target))
                {
                    _targetUnseenTicks = 0;
                }
                else if (_targetUnseenTicks++ > 60)
                {
                    return(false);
                }

                _entity.SetTarget(target);                 // This makes sense when we to attacked by targeting
            }

            return(true);
        }
        public override bool CanContinue()
        {
            // Give the poor entity a chance to survive
            // Also makes it let go of unreachable targets
            if (_entity.Level.Random.Next(_attackChance) == 0)
            {
                return(false);
            }

            var target = _entity.Target;

            if (target == null)
            {
                return(false);
            }

            if (target.HealthManager.IsDead)
            {
                return(false);
            }


            if (_entity.DistanceTo(target) > _targetDistance)
            {
                return(false);
            }

            if (_entity.CanSee(target))
            {
                _targetUnseenTicks = 0;
            }
            else if (_targetUnseenTicks++ > 60)
            {
                return(false);
            }

            _entity.SetTarget(target);             // This makes sense when we to attacked by targeting

            return(true);
        }
Exemple #3
0
        public override void OnTick(Entity[] entities)
        {
            Entity target = _entity.Target;

            if (target == null)
            {
                return;
            }

            double distanceToPlayer = _entity.DistanceTo(target);

            --_delay;

            float deltaDistance = Vector3.Distance(_lastPlayerPos, target.KnownPosition);

            bool canSee = _entity.CanSee(target);

            if (canSee || _delay <= 0 || deltaDistance > 1 || _entity.Level.Random.NextDouble() < 0.05)
            {
                var       pathfinder = new Pathfinder();
                Stopwatch sw         = Stopwatch.StartNew();
                _currentPath = pathfinder.FindPath(_entity, target, _followRange);
                if (Log.IsDebugEnabled)
                {
                    sw.Stop();
                    if (sw.ElapsedMilliseconds > 5)
                    {
                        Log.Warn($"A* search for {_entity.GetType()} on a distance of {_followRange}. Spent {sw.ElapsedMilliseconds}ms and lenght of path is {_currentPath.Current.Count}");
                    }
                    // DEBUG
                    //_currentPath.PrintPath(_entity.Level);
                }

                _lastPlayerPos = target.KnownPosition;

                _delay = 4 + _entity.Level.Random.Next(7);

                if (distanceToPlayer > 32)
                {
                    _delay += 10;
                }
                else if (distanceToPlayer > 16)
                {
                    _delay += 5;
                }

                if (_currentPath.NoPath())
                {
                    _delay += 15;
                }
            }

            // Movement
            if (_currentPath.HavePath())
            {
                if (_currentPath.GetNextTile(_entity, out Tile next /*, true*/))
                {
                    _entity.Controller.RotateTowards(new Vector3(next.X + 0.5f, _entity.KnownPosition.Y, next.Y + 0.5f));
                    _entity.Controller.MoveForward(_speedMultiplier, entities);
                }                 // else something is really wrong
            }
            else
            {
                _entity.Velocity = Vector3.Zero;
            }

            _entity.Controller.LookAt(target);

            _attackCooldown = Math.Max(_attackCooldown - 1, 0);
            if (_attackCooldown <= 0 && distanceToPlayer < GetAttackReach())
            {
                var damage = _entity.AttackDamage;
                target.HealthManager.TakeHit(_entity, damage, DamageCause.EntityAttack);
                _attackCooldown = 20;
            }
        }