From da0563066d4dc554f5078a44c4ced1a733f68063 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Wed, 15 Feb 2023 19:50:10 +0100 Subject: [PATCH] feat(pathfinding): add MateWalkTo to WalkManager --- .../WalkManager.cs | 97 +++++++++++++++++-- 1 file changed, 88 insertions(+), 9 deletions(-) diff --git a/Extensions/NosSmooth.Extensions.Pathfinding/WalkManager.cs b/Extensions/NosSmooth.Extensions.Pathfinding/WalkManager.cs index 03d4943..5cb694d 100644 --- a/Extensions/NosSmooth.Extensions.Pathfinding/WalkManager.cs +++ b/Extensions/NosSmooth.Extensions.Pathfinding/WalkManager.cs @@ -7,6 +7,7 @@ using NosSmooth.Core.Client; using NosSmooth.Core.Commands.Walking; using NosSmooth.Core.Errors; +using NosSmooth.Extensions.Pathfinding.Errors; using Remora.Results; namespace NosSmooth.Extensions.Pathfinding; @@ -34,7 +35,7 @@ public class WalkManager } /// - /// Go to the given position. + /// Move character to the given position. /// /// /// Expect if the destination could not be reached. @@ -44,31 +45,109 @@ public class WalkManager /// The target y coordinate. /// Whether to allow user actions during the walk operation. /// The cancellation token used for cancelling the operation. - /// The positions to walk pets to. /// A result that may not succeed. - public async Task GoToAsync(short x, short y, bool allowUserActions = true, CancellationToken ct = default, params (int Selector, short TargetX, short TargetY)[] pets) + public async Task PlayerGoToAsync + ( + short x, + short y, + bool allowUserActions = true, + CancellationToken ct = default + ) { var pathResult = _pathfinder.FindPathFromCurrent(x, y); - if (!pathResult.IsSuccess) + if (!pathResult.IsDefined(out var path)) { return Result.FromError(pathResult); } - if (pathResult.Entity.Parts.Count == 0) + return await TakePath + ( + path, + _state.Character, + (x, y) => _client.SendCommandAsync + ( + new WalkCommand + ( + x, + y, + 2, + AllowUserCancel: allowUserActions + ), + ct + ) + ); + } + + /// + /// Move pet to the given position. + /// + /// + /// Expect if the destination could not be reached. + /// Expect if the path could not be found. + /// + /// The id of the mate to move. + /// The target x coordinate. + /// The target y coordinate. + /// Whether to allow user actions during the walk operation. + /// The cancellation token used for cancelling the operation. + /// A result that may not succeed. + public async Task MateWalkToAsync + ( + long mateId, + short x, + short y, + bool allowUserActions = true, + CancellationToken ct = default + ) + { + if (!_state.Entities.TryGetValue(mateId, out var entityState) || entityState == _state.Character) + { + return new EntityStateNotFoundError(mateId); + } + + var pathResult = _pathfinder.FindPathFromEntity(mateId, x, y); + + if (!pathResult.IsDefined(out var path)) + { + return Result.FromError(pathResult); + } + + return await TakePath + ( + path, + entityState, + (x, y) => _client.SendCommandAsync + ( + new MateWalkCommand + ( + mateId, + x, + y, + 2, + AllowUserCancel: allowUserActions + ), + ct + ) + ); + } + + private async Task TakePath(Path path, EntityState state, Func> walkFunc) + { + if (path.Parts.Count == 0) { return Result.FromSuccess(); } + var target = path.Parts.Last(); - var path = pathResult.Entity; while (!path.ReachedEnd) { if (path.MapId != _state.MapId) { - return new WalkNotFinishedError(_state.X, _state.Y, WalkUnfinishedReason.MapChanged); + return new WalkNotFinishedError(state.X, state.Y, WalkUnfinishedReason.MapChanged); } var next = path.TakeForwardPath(); - var walkResult = await _client.SendCommandAsync(new WalkCommand(next.X, next.Y, pets, 2, AllowUserCancel: allowUserActions), ct); + var walkResult = await walkFunc(next.X, next.Y); if (!walkResult.IsSuccess) { if (path.ReachedEnd && walkResult.Error is WalkNotFinishedError walkNotFinishedError @@ -77,7 +156,7 @@ public class WalkManager return Result.FromSuccess(); } - if (_state.X == x && _state.Y == y) + if (state.X == target.X && state.Y == target.Y) { return Result.FromSuccess(); } -- 2.48.1