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; } }
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); }
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); }
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(); } }
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); }