~ruther/NosSmooth

ref: 56dfefc0597f6a6683c109908e3b8bea46761f15 NosSmooth/Extensions/NosSmooth.Extensions.Pathfinding/WalkManager.cs -rw-r--r-- 3.2 KiB
56dfefc0 — Rutherther feat(tests): add tests structure 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//
//  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;

/// <summary>
/// The walk manager using pathfinding to walk to given position.
/// </summary>
public class WalkManager
{
    private readonly INostaleClient _client;
    private readonly Pathfinder _pathfinder;
    private readonly PathfinderState _state;

    /// <summary>
    /// Initializes a new instance of the <see cref="WalkManager"/> class.
    /// </summary>
    /// <param name="client">The client.</param>
    /// <param name="pathfinder">The pathfinder.</param>
    /// <param name="state">The state.</param>
    public WalkManager(INostaleClient client, Pathfinder pathfinder, PathfinderState state)
    {
        _client = client;
        _pathfinder = pathfinder;
        _state = state;
    }

    /// <summary>
    /// Go to the given position.
    /// </summary>
    /// <remarks>
    /// Expect <see cref="WalkNotFinishedError"/> if the destination could not be reached.
    /// Expect <see cref="NotFoundError"/> if the path could not be found.
    /// </remarks>
    /// <param name="x">The target x coordinate.</param>
    /// <param name="y">The target y coordinate.</param>
    /// <param name="allowUserActions">Whether to allow user actions during the walk operation.</param>
    /// <param name="ct">The cancellation token used for cancelling the operation.</param>
    /// <param name="petSelectors">The pet selectors to go with.</param>
    /// <returns>A result that may not succeed.</returns>
    public async Task<Result> GoToAsync(short x, short y, bool allowUserActions = true, CancellationToken ct = default, params int[] petSelectors)
    {
        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, petSelectors, 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();
    }
}
Do not follow this link