private void Move() { // Normal Move Mode if (Monster == null || !IsAlive) { return; } if (IsMoving && Monster.Speed > 0) { double time = (DateTime.Now - LastMove).TotalMilliseconds; if (Path.Any()) { int timetowalk = 2000 / Monster.Speed; if (time > timetowalk) { int maxindex = Path.Count > Monster.Speed / 2 ? Monster.Speed / 2 : Path.Count; short mapX = Path.ElementAt(maxindex - 1).X; short mapY = Path.ElementAt(maxindex - 1).Y; double waitingtime = Map.GetDistance(new MapCell { X = mapX, Y = mapY }, new MapCell { X = MapX, Y = MapY }) / (double)Monster.Speed; LastMove = DateTime.Now.AddSeconds(waitingtime > 1 ? 1 : waitingtime); Observable.Timer(TimeSpan.FromMilliseconds(timetowalk)) .Subscribe( x => { MapX = (short)mapX; MapY = (short)mapY; MoveEvent?.Events.ForEach(e => { EventHelper.Instance.RunEvent(e, monster: this); }); if (MoveEvent != null && MoveEvent.InZone(MapX, MapY)) { MoveEvent = null; } }); Path.RemoveRange(0, maxindex); MapInstance.Broadcast(new BroadcastPacket(null, GenerateMv3(), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY)); return; } } else if (time > _movetime && Target == -1) { short mapX = FirstX, mapY = FirstY; if (MapInstance.Map?.GetFreePosition(ref mapX, ref mapY, (byte)ServerManager.Instance.RandomNumber(0, 2), (byte)_random.Next(0, 2)) ?? false) { int distance = Map.GetDistance(new MapCell { X = mapX, Y = mapY }, new MapCell { X = MapX, Y = MapY }); double value = 1000d * distance / (2 * Monster.Speed); Observable.Timer(TimeSpan.FromMilliseconds(value)) .Subscribe( x => { MapX = mapX; MapY = mapY; }); LastMove = DateTime.Now.AddMilliseconds(value); MapInstance.Broadcast(new BroadcastPacket(null, GenerateMv3(), ReceiverType.All)); } } } HostilityTarget(); }