//
// AttackCommandHandler.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;
using NosSmooth.Core.Commands.Attack;
using NosSmooth.Core.Commands.Control;
using NosSmooth.Core.Extensions;
using NosSmooth.LocalBinding;
using NosSmooth.LocalBinding.Objects;
using NosSmooth.LocalBinding.Structs;
using Remora.Results;
namespace NosSmooth.LocalClient.CommandHandlers.Attack;
///
/// Handler of .
///
public class AttackCommandHandler : ICommandHandler
{
private readonly INostaleClient _nostaleClient;
private readonly NosThreadSynchronizer _synchronizer;
private readonly UnitManagerBinding _unitManagerBinding;
private readonly SceneManager _sceneManager;
///
/// Initializes a new instance of the class.
///
/// The NosTale client.
/// The thread synchronizer.
/// The unit manager binding.
/// The scene manager.
public AttackCommandHandler
(
INostaleClient nostaleClient,
NosThreadSynchronizer synchronizer,
UnitManagerBinding unitManagerBinding,
SceneManager sceneManager
)
{
_nostaleClient = nostaleClient;
_synchronizer = synchronizer;
_unitManagerBinding = unitManagerBinding;
_sceneManager = sceneManager;
}
///
public async Task HandleCommand(AttackCommand command, CancellationToken ct = default)
{
if (command.TargetId is not null)
{
var entityResult = _sceneManager.FindEntity(command.TargetId.Value);
if (entityResult.IsDefined(out var entity))
{
_synchronizer.EnqueueOperation(() => _unitManagerBinding.FocusEntity(entity));
}
}
ControlCancelReason? reason = null;
var takeControlCommand = command.CreateTakeControl
(
"Attack",
command.HandleAttackCallback,
(r) =>
{
reason = r;
return Task.FromResult(Result.FromSuccess());
}
);
try
{
var result = await _nostaleClient.SendCommandAsync(takeControlCommand, ct);
if (!result.IsSuccess)
{
return result;
}
if (reason is not null)
{
return new GenericError($"The command could not finish, because {reason}");
}
}
catch (TaskCanceledException)
{
// ignored
}
return Result.FromSuccess();
}
}