/// <summary>
        /// Threadsafe way of dequeueing next task
        /// </summary>
        private PathfinderTask Next()
        {
            PathfinderTask task = null;

            if (!PathfinderTasks.TryDequeue(out task))
            {
                task = null;
            }
            return(task);
        }
 public override void Stop()
 {
     Active = false;
     entity.Controls.Forward       = false;
     entity.ServerControls.Forward = false;
     entity.Controls.WalkVector.Set(0, 0, 0);
     stuckCounter      = 0;
     distCheckAccum    = 0;
     prevPosAccum      = 0;
     asyncSearchObject = null;
 }
        private void FindPath_Async(BlockPos startBlockPos, BlockPos targetBlockPos, int searchDepth, int mhdistanceTolerance = 0)
        {
            waypointToReachIndex = 0;

            var   bh            = entity.GetBehavior <EntityBehaviorControlledPhysics>();
            float stepHeight    = bh == null ? 0.6f : bh.stepHeight;
            bool  avoidFall     = entity.Properties.FallDamage && entity.Properties.Attributes?["reckless"].AsBool(false) != true;
            int   maxFallHeight = avoidFall ? 4 - (int)(movingSpeed * 30) : 12; // fast moving entities cannot safely fall so far (might miss target block below due to outward drift)

            asyncSearchObject = new PathfinderTask(startBlockPos, targetBlockPos, maxFallHeight, stepHeight, entity.CollisionBox, searchDepth, mhdistanceTolerance);
            asyncPathfinder.EnqueuePathfinderTask(asyncSearchObject);
        }
        public bool AfterFoundPath()
        {
            if (asyncSearchObject != null)
            {
                newWaypoints      = asyncSearchObject.waypoints;
                asyncSearchObject = null;
            }

            if (newWaypoints == null /*|| newWaypoints.Count == 0 - uh no. this is a successful search*/)
            {
                HandleNoPath();
                return(false);
            }

            waypoints = newWaypoints;

            // Debug visualization

            /*List<BlockPos> poses = new List<BlockPos>();
             * List<int> colors = new List<int>();
             * int i = 0;
             * foreach (var node in waypoints)
             * {
             *  poses.Add(node.AsBlockPos);
             *  colors.Add(ColorUtil.ColorFromRgba(128, 128, Math.Min(255, 128 + i*8), 150));
             *  i++;
             * }
             *
             * poses.Add(desiredTarget.AsBlockPos);
             * colors.Add(ColorUtil.ColorFromRgba(128, 0, 255, 255));
             *
             * IPlayer player = entity.World.AllOnlinePlayers[0];
             * entity.World.HighlightBlocks(player, 2, poses,
             *  colors,
             *  API.Client.EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary
             * );*/

            waypoints.Add(desiredTarget);

            base.WalkTowards(desiredTarget, movingSpeed_New, targetDistance_New, OnGoalReached_New, OnStuck_New);

            return(true);
        }
 public void EnqueuePathfinderTask(PathfinderTask task)
 {
     PathfinderTasks.Enqueue(task);
 }
 public List <Vec3d> FindPathAsWaypoints(PathfinderTask task)
 {
     return(astar.FindPathAsWaypoints(task.startBlockPos, task.targetBlockPos, task.maxFallHeight, task.stepHeight, task.collisionBox, task.searchDepth, task.mhdistanceTolerance));
 }