public void MoveTo(Position destination) { if (destination.MapID != Player.MapID) { Log("Trying to move to another map", Client.UI.LogLevel.Warning); HandleTriggerInput(TriggerActionType.DestinationReached, false); return; } Path path = null; using(var detour = new DetourCLIR.Detour()) { List<DetourCLIR.Point> resultPath; bool successful = detour.FindPath(Player.X, Player.Y, Player.Z, destination.X, destination.Y, destination.Z, Player.MapID, out resultPath); if (!successful) { HandleTriggerInput(TriggerActionType.DestinationReached, false); return; } path = new Path(resultPath, Player.Speed); var destinationPoint = path.Destination; destination.SetPosition(destinationPoint.X, destinationPoint.Y, destinationPoint.Z); } var remaining = destination - Player.GetPosition(); // check if we even need to move if (remaining.Length < MovementEpsilon) { HandleTriggerInput(TriggerActionType.DestinationReached, true); 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(() => { Point progressPosition = path.MoveAlongPath((float)(DateTime.Now - previousMovingTime).TotalSeconds); Player.SetPosition(progressPosition.X, progressPosition.Y, progressPosition.Z); 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); HandleTriggerInput(TriggerActionType.DestinationReached, true); } }, 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.MapID != Player.MapID) { Log("Trying to follow a target on another map", Client.UI.LogLevel.Warning); CancelActionsByFlag(ActionFlag.Movement); return; } var distance = target - Player.GetPosition(); // check if we even need to move if (distance.Length < MovementEpsilon) { if (path != null) { var stopMoving = new MovementPacket(WorldCommand.MSG_MOVE_STOP) { GUID = Player.GUID, X = pathEndPosition.X, Y = pathEndPosition.Y, Z = pathEndPosition.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 >= MovementEpsilon && distance.Length <= FollowTargetRecalculatePathEpsilon) path = null; if (path == null) { using (var detour = new DetourCLIR.Detour()) { List<DetourCLIR.Point> resultPath; bool successful = detour.FindPath(Player.X, Player.Y, Player.Z, target.X, target.Y, target.Z, Player.MapID, out resultPath); if (!successful) { HandleTriggerInput(TriggerActionType.DestinationReached, false); CancelActionsByFlag(ActionFlag.Movement); return; } path = new Path(resultPath, Player.Speed); pathEndPosition = target.GetPosition(); } } if (!moving) { moving = true; 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 = distance.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); 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(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); }, new TimeSpan(0, 0, 0, 0, 100), flags: ActionFlag.Movement); }