Пример #1
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;
            }
        }
Пример #2
0
        public void OnTick(Entity[] entities)
        {
            if (_entity.Owner == null)
            {
                return;
            }
            //Player player = (Player) _entity.Owner;
            Entity player = _entity.Owner;

            var distanceToPlayer = _entity.KnownPosition.DistanceTo(player.KnownPosition);

            if (distanceToPlayer < 1.75)
            {
                // if within 6m stop following (walking)
                _entity.Velocity = Vector3.Zero;
                _entity.Controller.LookAt(player);
                return;
            }

            if (_currentPath == null || _currentPath.Count == 0)
            {
                Log.Debug($"Search new solution");
                var pathFinder = new Pathfinder();
                _currentPath = pathFinder.FindPath(_entity, player, distanceToPlayer + 1);
                if (_currentPath.Count == 0)
                {
                    _currentPath = pathFinder.FindPath(_entity, player, _lookDistance);
                }
            }

            if (_currentPath.Count > 0)
            {
                ImprovedTile next;
                if (!GetNextTile(out next))
                {
                    return;
                }

                _entity.Controller.RotateTowards(new Vector3((float)next.X + 0.5f, _entity.KnownPosition.Y, (float)next.Y + 0.5f));

                if (distanceToPlayer < 1.75)
                {
                    // if within 6m stop following (walking)
                    _entity.Velocity = Vector3.Zero;
                    _currentPath     = null;
                }
                else
                {
                    // else find path to player

                    var m = 2 - distanceToPlayer;
                    if (m <= 0)
                    {
                        m = 1;
                    }
                    else
                    {
                        m = m / 2.0;
                    }
                    //double m = 1;
                    _entity.Controller.MoveForward(_speedMultiplier * m, entities);
                }
            }
            else
            {
                Log.Debug($"Found no path solution");
                if (distanceToPlayer >= 16)
                {
                    _entity.KnownPosition = player.KnownPosition;
                }

                _entity.Velocity = Vector3.Zero;
                _currentPath     = null;
            }

            _entity.Controller.LookAt(player, true);
        }
Пример #3
0
        public override void OnTick(Entity[] entities)
        {
            if (_entity.Owner == null)
            {
                return;
            }
            Player owner = (Player)_entity.Owner;

            var distanceToPlayer = _entity.DistanceTo(owner);

            if (distanceToPlayer < 1.75)
            {
                _entity.Velocity = Vector3.Zero;
                _entity.Controller.LookAt(owner);
                return;
            }

            if (_currentPath == null || _currentPath.NoPath())
            {
                Log.Debug($"Search new solution");
                var pathFinder = new Pathfinder();
                _currentPath = pathFinder.FindPath(_entity, owner, _lookDistance);
            }

            if (_currentPath.HavePath())
            {
                if (!_currentPath.GetNextTile(_entity, out Tile next))
                {
                    return;
                }

                _entity.Controller.RotateTowards(new Vector3((float)next.X + 0.5f, _entity.KnownPosition.Y, (float)next.Y + 0.5f));

                if (distanceToPlayer < 1.75)
                {
                    _entity.Velocity = Vector3.Zero;
                    _currentPath     = null;
                }
                else
                {
                    // else find path to player

                    var m = 2 - distanceToPlayer;
                    if (m <= 0)
                    {
                        m = 1;
                    }
                    else
                    {
                        m = m / 2.0;
                    }
                    //double m = 1;
                    _entity.Controller.MoveForward(_speedMultiplier * m, entities);
                }
            }
            else
            {
                Log.Debug($"Found no path solution");
                _entity.Velocity = Vector3.Zero;
                _currentPath     = null;
            }

            _entity.Controller.LookAt(owner);
        }
Пример #4
0
        public void OnTick(Entity[] entities)
        {
            if (_fuse <= 0)
            {
                return;
            }

            Mob    entity = _entity;
            Entity target = _entity.Target;

            if (target == null)
            {
                return;
            }

            var distanceToPlayer = entity.KnownPosition.DistanceTo(target.KnownPosition);

            var haveNoPath = (_currentPath == null || _currentPath.Count == 0);

            if (haveNoPath || Vector3.Distance(_lastPlayerPos, target.KnownPosition) > 0.01)
            {
                Log.Debug($"Search new solution. Have no path={haveNoPath}");
                var pathFinder = new Pathfinder();
                _currentPath = pathFinder.FindPath(entity, target, distanceToPlayer + 1);
                if (_currentPath.Count == 0)
                {
                    Log.Debug($"Found no solution, trying a search at full distance");
                    _currentPath = pathFinder.FindPath(entity, target, _followRange);
                }
            }

            if (distanceToPlayer <= 7)
            {
                _fuse--;

                if (_fuse == 0)
                {
                    if (_damageWorld)
                    {
                        Explosion explosion = new Explosion(entity.Level, entity.KnownPosition.GetCoordinates3D(), 3);
                        explosion.Explode();
                    }

                    var playerVictims = _entity.Level.Players
                                        .OrderBy(p => Vector3.Distance(_entity.KnownPosition, p.Value.KnownPosition))
                                        .Where(p => p.Value.IsSpawned && _entity.DistanceTo(p.Value) < 7).Select(x => x.Value).ToArray();
                    var victims = new Entity[entities.Length + playerVictims.Length];
                    entities.CopyTo(victims, 0);
                    playerVictims.CopyTo(victims, entities.Length);
                    foreach (var victim in victims)
                    {
                        var dist = entity.KnownPosition.DistanceTo(victim.KnownPosition);
                        if (dist <= 7)
                        {
                            victim.HealthManager.TakeHit(_entity, (int)((1D / Math.Max(dist, 1D)) * 49D), DamageCause.EntityExplosion);
                        }
                    }

                    _entity.DespawnEntity();
                }
            }
            else
            {
                _fuse          = 30;        //
                _lastPlayerPos = target.KnownPosition;

                if (_currentPath.Count > 0)
                {
                    ImprovedTile next;
                    if (GetNextTile(out next))
                    {
                        entity.Controller.RotateTowards(new Vector3((float)next.X + 0.5f, entity.KnownPosition.Y, (float)next.Y + 0.5f));
                        entity.Controller.MoveForward(_speedMultiplier, entities);
                    }
                }
                else
                {
                    Log.Debug($"Found no path solution");
                    entity.Velocity = Vector3.Zero;
                    _currentPath    = null;
                }
                entity.Controller.LookAt(target, true);
            }

            if (_entity is Creeper c && c.Fuse != _fuse)
            {
                c.Fuse = _fuse;
                if (_fuse < 30 && _fuse >= 0)
                {
                    c.IsIgnited = true;
                }
                else
                {
                    c.IsIgnited = false;
                }
                c.BroadcastSetEntityData();
            }
        }
Пример #5
0
        public override void OnTick(Entity[] entities)
        {
            if (_temptingPlayer == null)
            {
                return;
            }
            var distanceToPlayer = _entity.DistanceTo(_temptingPlayer);

            if (distanceToPlayer < 1.75)
            {
                _entity.Velocity = Vector3.Zero;
                _entity.Controller.LookAt(_temptingPlayer);

                _entity.Controller.RotateTowards(_temptingPlayer.KnownPosition);
                _entity.Direction             = Mob.ClampDegrees(_entity.Direction);
                _entity.KnownPosition.HeadYaw = (float)_entity.Direction;
                _entity.KnownPosition.Yaw     = (float)_entity.Direction;
                _currentPath = null;

                return;
            }

            bool haveNoPath    = (_currentPath == null || _currentPath.NoPath());
            var  deltaDistance = Vector3.Distance(_lastPlayerPos, _temptingPlayer.KnownPosition);

            if (haveNoPath || deltaDistance > 1)
            {
                _pathfinder    = new Pathfinder();
                _currentPath   = _pathfinder.FindPath(_entity, _temptingPlayer, _lookDistance);
                _lastPlayerPos = _temptingPlayer.KnownPosition;
            }


            if (_currentPath.HavePath())
            {
                if (!_currentPath.GetNextTile(_entity, out var next, true))
                {
                    _currentPath = null;
                    return;
                }

                _entity.Controller.RotateTowards(new Vector3((float)next.X + 0.5f, _entity.KnownPosition.Y, (float)next.Y + 0.5f));
                _entity.Direction             = Mob.ClampDegrees(_entity.Direction);
                _entity.KnownPosition.HeadYaw = (float)_entity.Direction;
                _entity.KnownPosition.Yaw     = (float)_entity.Direction;

                if (distanceToPlayer < 1.75)
                {
                    // if within x m stop following (walking)
                    _entity.Velocity = Vector3.Zero;
                    _currentPath     = null;
                }
                else
                {
                    // else find path to player

                    var m = 2 - distanceToPlayer;
                    if (m <= 0)
                    {
                        m = 1;
                    }
                    else
                    {
                        m = m / 2.0;
                    }
                    //double m = 1;
                    _entity.Controller.MoveForward(_speedMultiplier * m, entities);
                }
            }
            else
            {
                _entity.Velocity = Vector3.Zero;
                _currentPath     = null;
            }

            _entity.Controller.LookAt(_temptingPlayer);
        }