// // WalkManager.cs // // Copyright (c) František Boháček. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using NosSmooth.Core.Client; using NosSmooth.Core.Commands.Walking; using NosSmooth.Core.Errors; using Remora.Results; namespace NosSmooth.Extensions.Pathfinding; /// /// The walk manager using pathfinding to walk to given position. /// public class WalkManager { private readonly INostaleClient _client; private readonly Pathfinder _pathfinder; private readonly PathfinderState _state; /// /// Initializes a new instance of the class. /// /// The client. /// The pathfinder. /// The state. public WalkManager(INostaleClient client, Pathfinder pathfinder, PathfinderState state) { _client = client; _pathfinder = pathfinder; _state = state; } /// /// Go to the given position. /// /// /// Expect if the destination could not be reached. /// Expect if the path could not be found. /// /// 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. /// 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) { var pathResult = _pathfinder.FindPathFromCurrent(x, y); if (!pathResult.IsSuccess) { return Result.FromError(pathResult); } if (pathResult.Entity.Parts.Count == 0) { return Result.FromSuccess(); } var path = pathResult.Entity; while (!path.ReachedEnd) { if (path.MapId != _state.MapId) { 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); if (!walkResult.IsSuccess) { if (path.ReachedEnd && walkResult.Error is WalkNotFinishedError walkNotFinishedError && walkNotFinishedError.Reason == WalkUnfinishedReason.MapChanged) { return Result.FromSuccess(); } if (_state.X == x && _state.Y == y) { return Result.FromSuccess(); } return walkResult; } } return Result.FromSuccess(); } }