private float GetTargetPositionX(BossBehaviour.TargetType type, Mobile mob)
        {
            switch (type)
            {
            case BossBehaviour.TargetType.NextToPlayer:
                var toPlayer = Mathf.Sign(_controller.Player.BodyPosition.x - mob.BodyPosition.x);
                return(ClampPositionX(
                           _controller.Player.BodyPosition.x - _settings.CombatRangeThreshold * toPlayer));

            case BossBehaviour.TargetType.FarthestCornerFromPlayer:
                var left   = _controller.GetHotSpotPosition(BossBehaviour.TargetType.LeftCorner).x;
                var right  = _controller.GetHotSpotPosition(BossBehaviour.TargetType.RightCorner).x;
                var player = _controller.Player.BodyPosition.x;
                return(Mathf.Abs(player - left) < Mathf.Abs(player - right) ? right : left);

            case BossBehaviour.TargetType.OntoPlayer:
                return(ClampPositionX(_controller.Player.BodyPosition.x));

            case BossBehaviour.TargetType.LeftPlatform:
            case BossBehaviour.TargetType.RightPlatform:
            case BossBehaviour.TargetType.LeftCorner:
            case BossBehaviour.TargetType.Center:
            case BossBehaviour.TargetType.RightCorner:
            default:
                return(_controller.GetHotSpotPosition(type).x);
            }
        }
        private IEnumerable MoveResolver(BossActor actor, BossBehaviour.TargetType type)
        {
            BossBehaviour.Log(actor + " moves to " + type, actor);
            var mob = actor.Mobile;

            var targetPositionX = GetTargetPositionX(type, mob);

            var toTarget = targetPositionX - mob.BodyPosition.x;

            if (Mathf.Abs(toTarget) < _settings.CloseRangeThreshold)
            {
                foreach (var unused in WalkResolver(actor, targetPositionX))
                {
                    yield return(null);
                }
            }
            else if (Mathf.Abs(toTarget) < _settings.MidRangeThreshold)
            {
                BossBehaviour.Log(Time.frameCount + " actor will jump to targetX", actor);

                foreach (var unused in JumpAndWaitForCompletion(actor, toTarget))
                {
                    DebugExtension.DebugArrow(mob.BodyPosition.WithX(targetPositionX), Vector3.down);

                    yield return(null);
                }
            }
            else
            {
                const float LongRangeWalkDistance = 2;
                var         movementDirection     = Mathf.Sign(toTarget);
                var         walkTargetX           = ClampPositionX(mob.BodyPosition.x + movementDirection * LongRangeWalkDistance);
                BossBehaviour.Log(Time.frameCount + " actor will first walk to walkTargetX", actor);

                foreach (var unused in WalkResolver(actor, walkTargetX))
                {
                    yield return(null);
                }

                BossBehaviour.Log(Time.frameCount + " then actor will jump to targetX", actor);
                foreach (var unused in JumpAndWaitForCompletion(actor, targetPositionX - mob.BodyPosition.x))
                {
                    DebugExtension.DebugArrow(mob.BodyPosition.WithX(targetPositionX), Vector3.down);

                    yield return(null);
                }
            }
        }
        private IEnumerable JumpAttackResolver(BossActor actor, BossBehaviour.TargetType type)
        {
            BossBehaviour.Log(actor + " jump attacks", actor);
            var mob = actor.Mobile;

            var targetPositionX = GetTargetPositionX(type, mob);
//            var targetPositionX = Mathf.Clamp( Player.BodyPosition.x, GetHotSpotPosition( TargetType.LeftCorner ).x,
//                GetHotSpotPosition( TargetType.RightCorner ).x );

            var delta = targetPositionX - actor.Mobile.BodyPosition.x;

            foreach (var unused in JumpAttackAndWaitForCompletion(actor, delta))
            {
                DebugExtension.DebugArrow(mob.BodyPosition.WithX(targetPositionX - delta), Vector3.up);

                DebugExtension.DebugArrow(mob.BodyPosition.WithX(targetPositionX), Vector3.down);
                yield return(null);
            }
        }
 public Vector2 GetHotSpotPosition(BossBehaviour.TargetType type)
 {
     return(_hotSpotsPositions[type]);
 }