public void MoveTo(Position destination) { const float MovementEpsilon = 1.0f; if (destination.MapID != Player.MapID) { Log("Trying to move to another map", Client.UI.LogLevel.Warning); return; } var remaining = destination - Player.GetPosition(); // check if we even need to move if (remaining.Length < MovementEpsilon) { return; } var direction = remaining.Direction; var facing = new MovementPacket(WorldCommand.MSG_MOVE_SET_FACING) { GUID = Player.GUID, flags = MovementFlags.MOVEMENTFLAG_FORWARD, X = Player.X, Y = Player.Y, Z = Player.Z, O = direction.O }; SendPacket(facing); Player.SetPosition(facing.GetPosition()); var startMoving = new MovementPacket(WorldCommand.MSG_MOVE_START_FORWARD) { GUID = Player.GUID, flags = MovementFlags.MOVEMENTFLAG_FORWARD, X = Player.X, Y = Player.Y, Z = Player.Z, O = Player.O }; SendPacket(startMoving); var previousMovingTime = DateTime.Now; var oldRemaining = remaining; ScheduleAction(() => { Player.SetPosition(Player.GetPosition() + direction * 7 * (DateTime.Now - previousMovingTime).TotalSeconds); previousMovingTime = DateTime.Now; remaining = destination - Player.GetPosition(); if (remaining.Length > MovementEpsilon && oldRemaining.Length > remaining.Length) { oldRemaining = remaining; var heartbeat = new MovementPacket(WorldCommand.MSG_MOVE_HEARTBEAT) { GUID = Player.GUID, flags = MovementFlags.MOVEMENTFLAG_FORWARD, X = Player.X, Y = Player.Y, Z = Player.Z, O = Player.O }; SendPacket(heartbeat); } else { var stopMoving = new MovementPacket(WorldCommand.MSG_MOVE_STOP) { GUID = Player.GUID, X = destination.X, Y = destination.Y, Z = destination.Z, O = Player.O }; SendPacket(stopMoving); Player.SetPosition(stopMoving.GetPosition()); CancelActionsByFlag(ActionFlag.Movement); } }, new TimeSpan(0, 0, 0, 0, 100), flags: ActionFlag.Movement); }
public void Follow(WorldObject target) { if (target == null) { return; } Path path = null; bool moving = false; Position pathEndPosition = target.GetPosition(); DateTime previousMovingTime = DateTime.MinValue; ScheduleAction(() => { if (!target.IsValid) { return; } if (target.MapID != Player.MapID) { Log("Trying to follow a target on another map", Client.UI.LogLevel.Warning); CancelActionsByFlag(ActionFlag.Movement, false); return; } var distance = target - Player.GetPosition(); // check if we even need to move if (distance.Length < FollowMovementEpsilon) { if (path != null) { var stopMoving = new MovementPacket(NetworkOperationCode.MSG_MOVE_STOP) { GUID = Player.GUID, X = Player.X, Y = Player.Y, Z = Player.Z, O = Player.O }; SendPacket(stopMoving); Player.SetPosition(stopMoving.GetPosition()); moving = false; path = null; HandleTriggerInput(TriggerActionType.DestinationReached, true); } return; } float targetMovement = (target - pathEndPosition).Length; if (targetMovement > FollowTargetRecalculatePathEpsilon) { path = null; } else if (distance.Length >= FollowMovementEpsilon && distance.Length <= FollowTargetRecalculatePathEpsilon) { path = null; } if (path == null) { using (var detour = new DetourCLI.Detour()) { List <MapCLI.Point> resultPath; var findPathResult = detour.FindPath(Player.X, Player.Y, Player.Z, target.X, target.Y, target.Z, Player.MapID, out resultPath); if (findPathResult != PathType.Complete) { HandleTriggerInput(TriggerActionType.DestinationReached, false); CancelActionsByFlag(ActionFlag.Movement); return; } path = new Path(resultPath, Player.Speed, Player.MapID); pathEndPosition = target.GetPosition(); } } if (!moving) { moving = true; var facing = new MovementPacket(NetworkOperationCode.MSG_MOVE_SET_FACING) { GUID = Player.GUID, flags = MovementFlags.MOVEMENTFLAG_FORWARD, X = Player.X, Y = Player.Y, Z = Player.Z, O = path.CurrentOrientation }; SendPacket(facing); Player.SetPosition(facing.GetPosition()); var startMoving = new MovementPacket(NetworkOperationCode.MSG_MOVE_START_FORWARD) { GUID = Player.GUID, flags = MovementFlags.MOVEMENTFLAG_FORWARD, X = Player.X, Y = Player.Y, Z = Player.Z, O = path.CurrentOrientation }; SendPacket(startMoving); previousMovingTime = DateTime.Now; return; } Point progressPosition = path.MoveAlongPath((float)(DateTime.Now - previousMovingTime).TotalSeconds); Player.SetPosition(progressPosition.X, progressPosition.Y, progressPosition.Z); previousMovingTime = DateTime.Now; var heartbeat = new MovementPacket(NetworkOperationCode.MSG_MOVE_HEARTBEAT) { GUID = Player.GUID, flags = MovementFlags.MOVEMENTFLAG_FORWARD, X = Player.X, Y = Player.Y, Z = Player.Z, O = path.CurrentOrientation }; SendPacket(heartbeat); }, new TimeSpan(0, 0, 0, 0, 100), flags: ActionFlag.Movement); }