// // EntityCommands.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.ChatCommands; using NosSmooth.Extensions.Combat.Errors; using NosSmooth.Game; using NosSmooth.Game.Apis; using NosSmooth.LocalBinding; using NosSmooth.LocalBinding.Objects; using NosSmooth.LocalBinding.Structs; using NosSmooth.Packets.Enums.Chat; using Remora.Commands.Attributes; using Remora.Commands.Groups; using Remora.Results; namespace SimplePiiBot.Commands; /// /// Represents command group for combat commands. /// public class EntityCommands : CommandGroup { private readonly Game _game; private readonly NosThreadSynchronizer _synchronizer; private readonly UnitManagerBinding _unitManagerBinding; private readonly SceneManager _sceneManager; private readonly PlayerManagerBinding _playerManagerBinding; private readonly FeedbackService _feedbackService; /// /// Initializes a new instance of the class. /// /// The game. /// The thread synchronizer. /// The scene manager binding. /// The scene manager. /// The character binding. /// The feedback service. public EntityCommands ( Game game, NosThreadSynchronizer synchronizer, UnitManagerBinding unitManagerBinding, SceneManager sceneManager, PlayerManagerBinding playerManagerBinding, FeedbackService feedbackService ) { _game = game; _synchronizer = synchronizer; _unitManagerBinding = unitManagerBinding; _sceneManager = sceneManager; _playerManagerBinding = playerManagerBinding; _feedbackService = feedbackService; } /// /// Show close entities. /// /// The range to look. /// A task that may or may not have succeeded. [Command("close")] public async Task HandleCloseEntitiesAsync(int range = 10) { var map = _game.CurrentMap; var character = _game.Character; if (map is null) { return new MapNotInitializedError(); } if (character is null) { return new CharacterNotInitializedError(); } var position = character.Position; if (position is null) { return new CharacterNotInitializedError("Position"); } var entities = map.Entities .GetEntities() .Where(x => x.Position?.DistanceSquared(position.Value) <= range * range) .ToList(); if (entities.Count == 0) { await _feedbackService.SendInfoMessageAsync("No entity found.", CancellationToken); } foreach (var entity in entities) { await _feedbackService.SendMessageAsync($"Found entity: {entity.Id}", SayColor.Yellow, CancellationToken); } return Result.FromSuccess(); } /// /// Focus the given entity. /// /// The entity id to focus. /// A task that may or may not have succeeded. [Command("focus")] public async Task HandleFocusAsync(int entityId) { var entityResult = _sceneManager.FindEntity(entityId); if (!entityResult.IsSuccess) { return Result.FromError(entityResult); } return await _synchronizer.SynchronizeAsync ( () => _unitManagerBinding.FocusEntity(entityResult.Entity), CancellationToken ); } /// /// Follow the given entity. /// /// The entity id to follow. /// A task that may or may not have succeeded. [Command("follow")] public async Task HandleFollowAsync(int entityId) { var entityResult = _sceneManager.FindEntity(entityId); if (!entityResult.IsSuccess) { return Result.FromError(entityResult); } return await _synchronizer.SynchronizeAsync ( () => _playerManagerBinding.FollowEntity(entityResult.Entity), CancellationToken ); } /// /// Stop following an entity. /// /// A task that may or may not have succeeded. [Command("unfollow")] public async Task HandleUnfollowAsync() { return await _synchronizer.SynchronizeAsync ( () => _playerManagerBinding.UnfollowEntity(), CancellationToken ); } }