using LavishVMAPI; using Microsoft.Extensions.Logging; using MRBot.IsxEq2; using MRBot.IsxEq2.CharacterActor; using MRBot.Navigation; using StackExchange.Profiling; namespace MRBot.PassiveTasks; internal sealed class FollowTask : IPassiveTask { private const int LeashDistance = 70; private const uint PulseRate = 5; private readonly int _followTargetId; private readonly ILogger _logger; private readonly MrNavigation _mrNavigation; private readonly MiniProfiler _profiler; private uint _pulseCount; public FollowTask( string targetName, MrNavigation mrNavigation, ILogger logger, MiniProfiler profiler) { _mrNavigation = mrNavigation; _logger = logger; _profiler = profiler; using (new FrameLock()) { _followTargetId = Extension.Actor("Name", targetName).ID; } } private bool ShouldPulse { get { if (_pulseCount < PulseRate) { _pulseCount++; return false; } _logger.LogInformation("Pulsing"); _pulseCount = 0; return true; } } public TaskType Type => TaskType.Follow; public void Execute() { _logger.LogInformation("Executing follow task"); // using (_profiler.Step("FollowTask.Execute")) { Actor followTarget; // using (_profiler.Step("FollowTask.Execute.GetFollowTarget")) { followTarget = Extension.Actor(_followTargetId); } // using (_profiler.Step("FollowTask.Execute.CheckFollowTargetIsValid")) { if (!followTarget.IsValid) { _logger.LogWarning("Follow target is invalid"); return; } } if (followTarget.Distance is > 5 and < LeashDistance) // using (_profiler.Step("FollowTask.Execute.RunTowardsPoint")) { _logger.LogInformation("Navigating to target ({targetX}, {targetZ})", followTarget.Loc.X, followTarget.Loc.Z); _mrNavigation.RunTowardsPoint(followTarget.Loc.X, followTarget.Loc.Z); } else // using (_profiler.Step("FollowTask.Execute.Stop")) { _logger.LogInformation("Stopping navigation"); _mrNavigation.Stop(); } } } }