From aca5dc59daa32196a869a5f8c47ee204f176a08b Mon Sep 17 00:00:00 2001 From: Rutherther Date: Thu, 27 Jan 2022 21:49:09 +0100 Subject: [PATCH] feat(core): add walk command for moving the player as well as pets simultaneously --- .../Commands/Walking/WalkCommand.cs | 32 ++++++ .../Commands/Walking/WalkCommandHandler.cs | 103 ++++++++++++++++++ .../Extensions/ServiceCollectionExtensions.cs | 4 +- 3 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 Core/NosSmooth.Core/Commands/Walking/WalkCommand.cs create mode 100644 Core/NosSmooth.Core/Commands/Walking/WalkCommandHandler.cs diff --git a/Core/NosSmooth.Core/Commands/Walking/WalkCommand.cs b/Core/NosSmooth.Core/Commands/Walking/WalkCommand.cs new file mode 100644 index 0000000..5c40d51 --- /dev/null +++ b/Core/NosSmooth.Core/Commands/Walking/WalkCommand.cs @@ -0,0 +1,32 @@ +// +// WalkCommand.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.Commands.Control; + +namespace NosSmooth.Core.Commands.Walking; + +/// +/// Walk player and pets simultaneously. +/// +/// The target x coordinate. +/// The target y coordinate. +/// The pet indices. +/// +/// +/// +public record WalkCommand +( + ushort TargetX, + ushort TargetY, + int[] PetSelectors, + bool CanBeCancelledByAnother = true, + bool WaitForCancellation = true, + bool AllowUserCancel = true +) : ITakeControlCommand +{ + /// + public bool CancelOnMapChange => true; +} \ No newline at end of file diff --git a/Core/NosSmooth.Core/Commands/Walking/WalkCommandHandler.cs b/Core/NosSmooth.Core/Commands/Walking/WalkCommandHandler.cs new file mode 100644 index 0000000..9eadcef --- /dev/null +++ b/Core/NosSmooth.Core/Commands/Walking/WalkCommandHandler.cs @@ -0,0 +1,103 @@ +// +// WalkCommandHandler.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 System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using NosSmooth.Core.Client; +using NosSmooth.Core.Extensions; +using Remora.Results; + +namespace NosSmooth.Core.Commands.Walking; + +/// +/// Handles . +/// +public class WalkCommandHandler : ICommandHandler +{ + private readonly INostaleClient _nostaleClient; + + /// + /// Initializes a new instance of the class. + /// + /// The NosTale client. + public WalkCommandHandler(INostaleClient nostaleClient) + { + _nostaleClient = nostaleClient; + } + + /// + public async Task HandleCommand(WalkCommand command, CancellationToken ct = default) + { + var tasks = new List>(); + for (var i = 0; i < command.PetSelectors.Length; i++) + { + short xOffset = (short)(-1 + (i % 3)); + short yOffset = (short)(-1 + ((i / 3) % 5)); + if (xOffset == 0 && yOffset == 0) + { + yOffset += 2; + } + + int x = command.TargetX; + int y = command.TargetY; + + if (x + xOffset > 0) + { + x += xOffset; + } + if (y + yOffset > 0) + { + y += yOffset; + } + + tasks.Add + ( + _nostaleClient.SendCommandAsync + ( + new PetWalkCommand + ( + command.PetSelectors[i], + (ushort)x, + (ushort)y, + command.CanBeCancelledByAnother, + command.WaitForCancellation, + command.AllowUserCancel + ), + ct + ) + ); + } + + tasks.Add + ( + _nostaleClient.SendCommandAsync + ( + new PlayerWalkCommand + ( + command.TargetX, + command.TargetY, + command.CanBeCancelledByAnother, + command.WaitForCancellation, + command.AllowUserCancel + ), + ct + ) + ); + + var results = await Task.WhenAll(tasks); + var errorResults = results.Where(x => !x.IsSuccess).ToArray(); + + return errorResults.Length switch + { + 0 => Result.FromSuccess(), + 1 => errorResults[0], + _ => new AggregateError(errorResults.Cast().ToArray()) + }; + } +} \ No newline at end of file diff --git a/Core/NosSmooth.Core/Extensions/ServiceCollectionExtensions.cs b/Core/NosSmooth.Core/Extensions/ServiceCollectionExtensions.cs index 57062b8..434b61e 100644 --- a/Core/NosSmooth.Core/Extensions/ServiceCollectionExtensions.cs +++ b/Core/NosSmooth.Core/Extensions/ServiceCollectionExtensions.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using NosSmooth.Core.Commands; using NosSmooth.Core.Commands.Control; +using NosSmooth.Core.Commands.Walking; using NosSmooth.Core.Packets; using NosSmooth.Packets.Extensions; @@ -40,7 +41,7 @@ public static class ServiceCollectionExtensions } /// - /// Adds command handling of . + /// Adds command handling of and . /// /// The service collection to register the responder to. /// The collection. @@ -49,6 +50,7 @@ public static class ServiceCollectionExtensions return serviceCollection .AddSingleton() .AddPacketResponder() + .AddCommandHandler() .AddCommandHandler(); } -- 2.49.0